Passed
Pull Request — master (#1)
by Andrey
04:43
created

SkrillClient::preparePayout()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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