Passed
Pull Request — master (#13)
by
unknown
02:29
created

SkrillClient::jsonHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Skrill;
6
7
use ArrayObject;
8
use LimitIterator;
9
use Skrill\Factory\VerificationServiceFactory;
10
use Skrill\Request\CustomerVerificationRequest;
11
use Skrill\ValueObject\SecretWord;
12
use SplFileObject;
13
use DateTimeInterface;
14
use Skrill\ValueObject\Sid;
15
use Skrill\ValueObject\Url;
16
use Skrill\ValueObject\Email;
17
use Skrill\Response\Response;
18
use Skrill\Factory\SidFactory;
19
use GuzzleHttp\RequestOptions;
20
use GuzzleHttp\ClientInterface;
21
use Skrill\Request\SaleRequest;
22
use Skrill\ValueObject\Password;
23
use Skrill\Request\PayoutRequest;
24
use Skrill\Request\RefundRequest;
25
use Skrill\Request\TransferRequest;
26
use Skrill\Factory\ResponseFactory;
27
use Skrill\Request\OnDemandRequest;
28
use Skrill\ValueObject\CompanyName;
29
use Skrill\Factory\HistoryItemFactory;
30
use Psr\Http\Message\ResponseInterface;
31
use GuzzleHttp\Exception\GuzzleException;
32
use Skrill\Exception\SkrillResponseException;
33
34
/**
35
 * Skrill HTTP client.
36
 */
37
final class SkrillClient implements
38
    SkrillHistoryClientInterface,
39
    SkrillOnDemandClientInterface,
40
    SkrillSaleClientInterface,
41
    SkrillTransferClientInterface,
42
    SkrillRefundClientInterface,
43
    SkrillCustomerVerificationClientInterface,
44
    SkrillPayoutClientInterface
45
{
46
    /**
47
     * @var ClientInterface
48
     */
49
    private $client;
50
51
    /**
52
     * A description to be shown on the Skrill payment page in the logo area if there is no logo_url parameter.
53
     *
54
     * recipient_description
55
     *
56
     * @var CompanyName|null
57
     */
58
    private $companyName;
59
60
    /**
61
     * Email address of your Skrill merchant account.
62
     *
63
     * pay_to_email
64
     *
65
     * @var Email
66
     */
67
    private $merchantEmail;
68
69
    /**
70
     * The URL of the logo which you would like to appear in the top right of the Skrill page.
71
     *
72
     * logo_url
73
     *
74
     * @var Url|null
75
     */
76
    private $logoUrl;
77
78
    /**
79
     * Skrill API/MQI password.
80
     *
81
     * @var string
82
     */
83
    private $password;
84
85
    /**
86
     * Skrill Secret Word
87
     *
88
     * @var SecretWord|null
89
     */
90
    private $secretWord;
91
92
    /**
93
     * @param ClientInterface $client
94
     * @param Email $merchantEmail
95
     * @param Password $password
96
     * @param Url|null $logoUrl
97
     * @param CompanyName|null $companyName
98
     * @param SecretWord|null $secretWord
99
     */
100
    public function __construct(
101
        ClientInterface $client,
102
        Email $merchantEmail,
103
        Password $password,
104
        Url $logoUrl = null,
105
        CompanyName $companyName = null,
106
        SecretWord $secretWord = null
107
    ) {
108
        $this->client = $client;
109
        $this->companyName = $companyName;
110
        $this->merchantEmail = $merchantEmail;
111
        $this->logoUrl = $logoUrl;
112
        $this->password = md5((string)$password);
113
        $this->secretWord = $secretWord;
114
    }
115
116
117
    /**
118
     * {@inheritdoc}
119
     * @throws GuzzleException
120
     */
121
    public function executeCustomerVerification(CustomerVerificationRequest $request): Response
122
    {
123
        $params = $request->getPayload();
124
        $params['password'] = $this->secretWord;
125
126
        return VerificationServiceFactory::createFromCustomerVerificationResponse(
127
            $this->request(array_filter($params), 'https://api.skrill.com/mqi/customer-verifications', 'json')
128
        );
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     *
134
     * @throws GuzzleException
135
     */
136
    public function prepareSale(SaleRequest $request): Sid
137
    {
138
        $params = $request->getPayload();
139
        $params['prepare_only'] = 1; // Forces only the SID to be returned without the actual page.
140
        $params['pay_to_email'] = (string)$this->merchantEmail;
141
142
        if (null != $this->logoUrl) {
143
            $params['logo_url'] = (string)$this->logoUrl;
144
        }
145
146
        if (null != $this->companyName) {
147
            $params['recipient_description'] = (string)$this->companyName;
148
        }
149
150
        return SidFactory::createFromSaleResponse(
151
            $this->request($params, 'https://pay.skrill.com')
152
        );
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     *
158
     * @throws GuzzleException
159
     */
160
    public function prepareTransfer(TransferRequest $request): Sid
161
    {
162
        $params = $request->getPayload();
163
        $params['action'] = 'prepare';
164
        $params['email'] = (string)$this->merchantEmail;
165
        $params['password'] = $this->password;
166
167
        return SidFactory::createFromXMLResponse(
168
            $this->request($params, 'https://www.skrill.com/app/pay.pl')
169
        );
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     *
175
     * @throws GuzzleException
176
     */
177
    public function preparePayout(PayoutRequest $request): Sid
178
    {
179
        $params = $request->getPayload();
180
        $params['action'] = 'prepare';
181
        $params['email'] = (string)$this->merchantEmail;
182
        $params['password'] = $this->password;
183
184
        return SidFactory::createFromXMLResponse(
185
            $this->request($params, 'https://www.skrill.com/app/pay.pl')
186
        );
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     *
192
     * @throws GuzzleException
193
     */
194
    public function prepareRefund(RefundRequest $request): Sid
195
    {
196
        $params = $request->getPayload();
197
        $params['action'] = 'prepare';
198
        $params['email'] = (string)$this->merchantEmail;
199
        $params['password'] = $this->password;
200
201
        return SidFactory::createFromXMLResponse(
202
            $this->request($params, 'https://www.skrill.com/app/refund.pl')
203
        );
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     *
209
     * @throws GuzzleException
210
     */
211
    public function executeTransfer(Sid $sid): Response
212
    {
213
        return ResponseFactory::createFromTransferResponse(
214
            $this->request(['action' => 'transfer', 'sid' => (string)$sid], 'https://www.skrill.com/app/pay.pl')
215
        );
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     *
221
     * @throws GuzzleException
222
     */
223
    public function executePayout(Sid $sid): Response
224
    {
225
        return ResponseFactory::createFromTransferResponse(
226
            $this->request(['action' => 'transfer', 'sid' => (string)$sid], 'https://www.skrill.com/app/pay.pl')
227
        );
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     *
233
     * @throws GuzzleException
234
     */
235
    public function executeRefund(Sid $sid): Response
236
    {
237
        return ResponseFactory::createFromRefundResponse(
238
            $this->request(['action' => 'refund', 'sid' => (string)$sid], 'https://www.skrill.com/app/refund.pl')
239
        );
240
    }
241
242
    /**
243
     * {@inheritdoc}
244
     *
245
     * @throws GuzzleException
246
     */
247
    public function prepareOnDemand(OnDemandRequest $request): Sid
248
    {
249
        $params = $request->getPayload();
250
        $params['action'] = 'prepare';
251
        $params['email'] = (string)$this->merchantEmail;
252
        $params['password'] = $this->password;
253
254
        return SidFactory::createFromXMLResponse(
255
            $this->request($params, 'https://www.skrill.com/app/ondemand_request.pl')
256
        );
257
    }
258
259
    /**
260
     * {@inheritdoc}
261
     *
262
     * @throws GuzzleException
263
     */
264
    public function executeOnDemand(Sid $sid): Response
265
    {
266
        return ResponseFactory::createFromTransferResponse(
267
            $this->request(
268
                ['action' => 'request', 'sid' => (string)$sid],
269
                'https://www.skrill.com/app/ondemand_request.pl'
270
            )
271
        );
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     *
277
     * @throws GuzzleException
278
     */
279
    public function viewHistory(DateTimeInterface $startDate, DateTimeInterface $endDate = null): ArrayObject
280
    {
281
        $params = [
282
            'email' => (string)$this->merchantEmail,
283
            'password' => $this->password,
284
            'action' => 'history',
285
            'start_date' => $startDate->format('d-m-Y'),
286
        ];
287
288
        if (null != $endDate) {
289
            $params['end_date'] = $endDate->format('d-m-y');
290
        }
291
292
        $tmpFile = new SplFileObject(tempnam(sys_get_temp_dir(), (string)mt_rand()), 'w+');
293
        $this->client->request(
294
            'POST',
295
            'https://www.skrill.com/app/query.pl',
296
            [
297
                RequestOptions::FORM_PARAMS => $params,
298
                RequestOptions::SINK => $tmpFile->getPathname(),
299
            ]
300
        );
301
302
        if (preg_match('/^[\d]{3}[\t]{2}(.+)$/', $tmpFile->current(), $matches)) {
303
            throw SkrillResponseException::fromSkillError($matches[1]);
304
        }
305
306
        $result = new ArrayObject();
307
        $tmpFile->rewind();
308
        $tmpFile->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
309
310
        foreach (new LimitIterator($tmpFile, 1) as $row) {
311
            $result->append(HistoryItemFactory::createFromRow($row));
312
        }
313
314
        unlink($tmpFile->getPathname());
315
316
        return $result;
317
    }
318
319
    /**
320
     * @param array $parameters
321
     * @param string $url
322
     * @param string $type
323
     * @param string $method
324
     * @return ResponseInterface
325
     *
326
     * @throws GuzzleException
327
     */
328
    private function request(array $parameters, string $url, string $type = 'xml', string $method = 'POST'): ResponseInterface
329
    {
330
        return $this->client->request($method, $url, $this->setHeaders($type, $parameters));
331
    }
332
333
    /**
334
     * @param string $type
335
     * @param array $parameters
336
     * @return array
337
     */
338
    private function setHeaders(string $type, array $parameters): array
339
    {
340
        if (method_exists( $this, "{$type}Headers")) {
341
            return $this->{"{$type}Headers"}($parameters);
342
        }
343
        return [];
344
    }
345
346
    /**
347
     * @param array $parameters
348
     * @return array
349
     */
350
    private function xmlHeaders(array $parameters): array
351
    {
352
        return [
353
            RequestOptions::FORM_PARAMS => $parameters,
354
            RequestOptions::HEADERS => ['Accept' => 'text/xml']
355
        ];
356
    }
357
358
    /**
359
     * @param array $parameters
360
     * @return array
361
     */
362
    private function jsonHeaders(array $parameters): array
363
    {
364
        return [
365
            RequestOptions::JSON => $parameters,
366
            RequestOptions::HEADERS => ['Accept' => 'application/json']
367
        ];
368
    }
369
}
370