Completed
Push — master ( dc8c3b...ad2432 )
by Dmitrii
03:27
created

Api::initTransaction()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.072

Importance

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