Passed
Push — master ( 5dcb3c...8498b3 )
by Roman
04:02
created

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