Completed
Pull Request — master (#5)
by Stefan
02:09
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php declare(strict_types=1);
2
3
namespace Karser\PayumSaferpay;
4
5
use Http\Message\MessageFactory;
6
use Karser\PayumSaferpay\Exception\SaferpayHttpException;
7
use Payum\Core\Bridge\Spl\ArrayObject;
8
use Payum\Core\Exception\InvalidArgumentException;
9
use Payum\Core\HttpClientInterface;
10
11
class Api
12
{
13
    const SPEC_VERSION = '1.10';
14
    const PAYMENT_PAGE_INIT_PATH = '/Payment/v1/PaymentPage/Initialize';
15
    const PAYMENT_PAGE_ASSERT_PATH = '/Payment/v1/PaymentPage/Assert';
16
    const TRANSACTION_INIT_PATH = '/Payment/v1/Transaction/Initialize';
17
    const TRANSACTION_AUTHORIZE_PATH = '/Payment/v1/Transaction/Authorize';
18
    const TRANSACTION_AUTHORIZE_REFERENCED_PATH = '/Payment/v1/Transaction/AuthorizeReferenced';
19
    const TRANSACTION_CAPTURE_PATH = '/Payment/v1/Transaction/Capture';
20
    const TRANSACTION_REFUND_PATH = '/Payment/v1/Transaction/Refund';
21
    const ALIAS_INSERT_PATH = '/Payment/v1/Alias/Insert';
22
    const ALIAS_ASSERT_INSERT_PATH = '/Payment/v1/Alias/AssertInsert';
23
    const ALIAS_DELETE_PATH = '/Payment/v1/Alias/Delete';
24
25
    /**
26
     * @var HttpClientInterface
27
     */
28
    protected $client;
29
30
    /**
31
     * @var MessageFactory
32
     */
33
    protected $messageFactory;
34
35
    /**
36
     * @var array
37
     */
38
    protected $options = array(
39
        'username' => null,
40
        'password' => null,
41
        'customerId' => null,
42
        'terminalId' => null,
43
        'sandbox' => null,
44
        'iframeCssUrl' => null,
45
    );
46
47
    /**
48
     * @param array               $options
49
     * @param HttpClientInterface $client
50
     * @param MessageFactory      $messageFactory
51
     */
52 34
    public function __construct(array $options, HttpClientInterface $client, MessageFactory $messageFactory)
53
    {
54 34
        $options = ArrayObject::ensureArrayObject($options);
55 34
        $options->defaults($this->options);
56 34
        $options->validateNotEmpty([
57 34
            'username', 'password', 'customerId', 'terminalId',
58
        ]);
59 33
        if (!is_bool($options['sandbox'])) {
60
            throw new InvalidArgumentException('The boolean sandbox option must be set.');
61
        }
62
63 33
        $this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like $options of type object<Payum\Core\Bridge\Spl\ArrayObject> is incompatible with the declared type array of property $options.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
64 33
        $this->client = $client;
65 33
        $this->messageFactory = $messageFactory;
66 33
    }
67
68
    /**
69
     * @param string $path
70
     * @param array $fields
71
     *
72
     * @return array
73 30
     */
74
    protected function doRequest($path, array $fields)
75
    {
76 30
        $headers = [
77 30
            'Authorization' => 'Basic ' . base64_encode($this->options['username'] . ':' . $this->options['password']),
78 30
            'Accept' => 'application/json',
79
            'Content-Type' => 'application/json',
80 30
        ];
81
        $fields = array_merge([
82 30
            'RequestHeader' => [
83 30
                'SpecVersion' => self::SPEC_VERSION,
84 30
                'CustomerId' => $this->options['customerId'],
85 30
                'RequestId' => uniqid(),
86
                'RetryIndicator' => 0,
87
            ],
88
        ], $fields);
89 30
90 30
        $request = $this->messageFactory->createRequest(
91 30
            'POST',
92
            $this->getApiEndpoint() . $path,
93 30
            $headers,
94
            json_encode($fields)
95
        );
96 30
97
        $response = $this->client->send($request);
98 30
99 2
        if (!($response->getStatusCode() >= 200 && $response->getStatusCode() < 300)) {
100
            throw SaferpayHttpException::factory($request, $response);
101
        }
102 29
103 29
        return $this->parseResponse(
104
            $response->getBody()->getContents()
105
        );
106
    }
107 29
108
    private function parseResponse($content)
109 29
    {
110
        return json_decode($content, true);
111
    }
112 13
113
    public function initTransaction(array $model): array
114
    {
115 13
        $payload = [
116 13
            'TerminalId' => $this->options['terminalId'],
117
            'Payment' => $model['Payment'],
118
            'Payer' => $model['Payer'] ?? [
119
                'LanguageCode' => 'en',
120 13
            ],
121
            'ReturnUrls' => $model['ReturnUrls'],
122 13
        ];
123
124
        if (null !== $this->options['iframeCssUrl']) {
125
            $payload['Styling'] = [
126
                'CssUrl' => $this->options['iframeCssUrl'],
127 13
            ];
128 3
        }
129
130 13
        $paymentMeans = $model['PaymentMeans'] ?? null;
131
132
        if (null !== $paymentMeans) {
133 6
            $payload['PaymentMeans'] = $paymentMeans;
134
        }
135
136 6
        return $this->doRequest(self::TRANSACTION_INIT_PATH, $payload);
137 6
    }
138
139
    public function initPaymentPage(array $model): array
140
    {
141 6
        $payload = [
142
            'TerminalId' => $this->options['terminalId'],
143 6
            'Payment' => $model['Payment'],
144
            'Payer' => $model['Payer'] ?? [
145
                'LanguageCode' => 'en',
146
            ],
147
            'ReturnUrls' => $model['ReturnUrls'],
148 6
        ];
149 6
150
        if (null !== $this->options['iframeCssUrl']) {
151 6
            $payload['Styling'] = [
152
                'CssUrl' => $this->options['iframeCssUrl'],
153
            ];
154 9
        }
155
156
        $notification = $model['Notification'] ?? null;
157 9
158
        if (null !== $notification) {
159 9
            $payload['Notification'] = $notification;
160 2
        }
161
162 9
        return $this->doRequest(self::PAYMENT_PAGE_INIT_PATH, $payload);
163 2
    }
164
165 9
    public function authorizeTransaction(string $token, ?string $condition = null, ?array $alias = null): array
166
    {
167
        $payload = [
168 3
            'Token' => $token,
169
        ];
170
        if (null !== $condition) {
171 3
            $payload['Condition'] = $condition;
172 3
        }
173 3
        if (null !== $alias) {
174
            $payload['RegisterAlias'] = array_merge(['IdGenerator' => Constants::ALIAS_ID_GENERATOR_RANDOM], $alias);
175 3
        }
176
        return $this->doRequest(self::TRANSACTION_AUTHORIZE_PATH, $payload);
177
    }
178 12
179
    public function authorizeReferencedTransaction(array $payment, string $transactionReferenceId): array
180
    {
181
        $payload = [
182 12
            'TerminalId' => $this->options['terminalId'],
183
            'Payment' => $payment,
184
            'TransactionReference' => ['TransactionId' => $transactionReferenceId],
185 12
        ];
186
        return $this->doRequest(self::TRANSACTION_AUTHORIZE_REFERENCED_PATH, $payload);
187
    }
188 2
189
    public function captureTransaction(string $transactionId): array
190
    {
191 2
        $payload = [
192
            'TransactionReference' => [
193 2
                'TransactionId' => $transactionId,
194
            ],
195
        ];
196 2
        return $this->doRequest(self::TRANSACTION_CAPTURE_PATH, $payload);
197
    }
198
199 4
    public function refundTransaction(array $refund, string $captureId): array
200
    {
201
        $payload = [
202 4
            'Refund' => $refund,
203
            'CaptureReference' => [
204 4
                'CaptureId' => $captureId,
205
            ],
206
        ];
207 4
        return $this->doRequest(self::TRANSACTION_REFUND_PATH, $payload);
208
    }
209
210 4
    public function assertPaymentPage(string $token): array
211 4
    {
212 4
        $payload = [
213 4
            'Token' => $token,
214
        ];
215 4
        return $this->doRequest(self::PAYMENT_PAGE_ASSERT_PATH, $payload);
216
    }
217
218 4
    public function insertAlias(array $returnUrls, array $alias, string $type): array
219
    {
220
        $payload = [
221 4
            'RegisterAlias' => $alias,
222
            'Type' => $type ?? Constants::ALIAS_TYPE_CARD,
223 4
            'ReturnUrls' => $returnUrls,
224
            'LanguageCode' => 'en',
225
        ];
226 2
        return $this->doRequest(self::ALIAS_INSERT_PATH, $payload);
227
    }
228
229 2
    public function assertInsertAlias(string $token): array
230
    {
231 2
        $payload = [
232
            'Token' => $token,
233
        ];
234
        return $this->doRequest(self::ALIAS_ASSERT_INSERT_PATH, $payload);
235
    }
236
237 32
    public function deleteAlias(string $id): array
238
    {
239 32
        $payload = [
240
            'AliasId' => $id,
241
        ];
242
        return $this->doRequest(self::ALIAS_DELETE_PATH, $payload);
243
    }
244
245 11
    /**
246
     * @return string
247 11
     */
248
    public function getApiEndpoint()
249
    {
250
        return $this->options['sandbox'] ? 'https://test.saferpay.com/api' : 'https://www.saferpay.com/api';
251 11
    }
252
253
    /**
254
     * @return string
255
     */
256
    public function getCaptureStrategy()
257
    {
258
        if (isset($this->options['interface']) && is_string($this->options['interface'])) {
259
            return $this->options['interface'];
260
        }
261
262
        return Constants::INTERFACE_TRANSACTION;
263
    }
264
}
265