Passed
Branch master (f21f03)
by Roman
02:50 queued 22s
created

SkrillClient::viewHistory()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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