Passed
Push — master ( cbde3b...f22511 )
by Abishek R
02:33
created

Transaction::getCapturedDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Greenlyst\BaseCommerce\Models;
6
7
use Carbon\Carbon;
8
use Greenlyst\BaseCommerce\ClientException;
9
use Greenlyst\BaseCommerce\Core\Helpers;
10
use Greenlyst\BaseCommerce\LogicException;
11
use Greenlyst\BaseCommerce\Traits\HasClient;
12
use Greenlyst\BaseCommerce\Traits\HasErrorMessages;
13
use function ArrayHelpers\array_get;
14
use function ArrayHelpers\array_set;
15
16
final class Transaction
17
{
18
    use HasClient, HasErrorMessages;
19
20
    private $transactionId;
21
    private $status;
22
    private $authorizationDate;
23
    private $capturedDate;
24
    private $amount;
25
    private $taxAmount;
26
    private $tipAmount;
27
    private $transactionType;
28
    private $responseCode;
29
    private $responseMessage;
30
    private $card;
31
32
    const TRANSACTION_STATUS_FAILED = 'FAILED';
33
    const TRANSACTION_STATUS_CREATED = 'CREATED';
34
    const TRANSACTION_STATUS_AUTHORIZED = 'AUTHORIZED';
35
    const TRANSACTION_STATUS_CAPTURED = 'CAPTURED';
36
    const TRANSACTION_STATUS_SETTLED = 'SETTLED';
37
    const TRANSACTION_STATUS_VOIDED = 'VOIDED';
38
    const TRANSACTION_STATUS_DECLINED = 'DECLINED';
39
    const TRANSACTION_STATUS_3D_SECURE = '3DSECURE';
40
    const TRANSACTION_STATUS_VERIFIED = 'VERIFIED';
41
42
    const TRANSACTION_TYPE_AUTHORIZE = 'AUTH';
43
    const TRANSACTION_TYPE_CAPTURE = 'CAPTURE';
44
    const TRANSACTION_TYPE_CREDIT = 'CREDIT';
45
    const TRANSACTION_TYPE_REFUND = 'REFUND';
46
    const TRANSACTION_TYPE_SALE = 'SALE';
47
    const TRANSACTION_TYPE_VOID = 'VOID';
48
49
    const URI_CARD_TRANSACTION = '/pcms/?f=API_processBankCardTransactionV4';
50
51
    /**
52
     * @return mixed
53
     */
54
    public function getTransactionId()
55
    {
56
        return $this->transactionId;
57
    }
58
59
    /**
60
     * @param mixed $transactionId
61
     */
62
    public function setTransactionId($transactionId): void
63
    {
64
        $this->transactionId = $transactionId;
65
    }
66
67
    /**
68
     * @return mixed
69
     */
70
    public function getStatus()
71
    {
72
        return $this->status;
73
    }
74
75
    /**
76
     * @param mixed $status
77
     */
78
    public function setStatus($status): void
79
    {
80
        $this->status = $status;
81
    }
82
83
    /**
84
     * @return mixed
85
     */
86
    public function getAuthorizationDate()
87
    {
88
        return $this->authorizationDate;
89
    }
90
91
    /**
92
     * @param mixed $authorizationDate
93
     */
94
    public function setAuthorizationDate($authorizationDate): void
95
    {
96
        $this->authorizationDate = $authorizationDate;
97
    }
98
99
    /**
100
     * @return mixed
101
     */
102
    public function getCapturedDate()
103
    {
104
        return $this->capturedDate;
105
    }
106
107
    /**
108
     * @param mixed $capturedDate
109
     */
110
    public function setCapturedDate($capturedDate): void
111
    {
112
        $this->capturedDate = $capturedDate;
113
    }
114
115
    /**
116
     * @return mixed
117
     */
118
    public function getAmount()
119
    {
120
        return $this->amount;
121
    }
122
123
    /**
124
     * @param mixed $amount
125
     */
126
    public function setAmount($amount): void
127
    {
128
        $this->amount = $amount;
129
    }
130
131
    /**
132
     * @return mixed
133
     */
134
    public function getTaxAmount()
135
    {
136
        return $this->taxAmount;
137
    }
138
139
    /**
140
     * @param mixed $taxAmount
141
     */
142
    public function setTaxAmount($taxAmount): void
143
    {
144
        $this->taxAmount = $taxAmount;
145
    }
146
147
    /**
148
     * @return mixed
149
     */
150
    public function getTipAmount()
151
    {
152
        return $this->tipAmount;
153
    }
154
155
    /**
156
     * @param mixed $tipAmount
157
     */
158
    public function setTipAmount($tipAmount): void
159
    {
160
        $this->tipAmount = $tipAmount;
161
    }
162
163
    /**
164
     * @return mixed
165
     */
166
    public function getTransactionType()
167
    {
168
        return $this->transactionType;
169
    }
170
171
    /**
172
     * @param mixed $transactionType
173
     */
174
    public function setTransactionType($transactionType): void
175
    {
176
        $this->transactionType = $transactionType;
177
    }
178
179
    /**
180
     * @return mixed
181
     */
182
    public function getResponseCode()
183
    {
184
        return $this->responseCode;
185
    }
186
187
    /**
188
     * @param mixed $responseCode
189
     */
190
    public function setResponseCode($responseCode): void
191
    {
192
        $this->responseCode = $responseCode;
193
    }
194
195
    /**
196
     * @return mixed
197
     */
198
    public function getResponseMessage()
199
    {
200
        return $this->responseMessage;
201
    }
202
203
    /**
204
     * @param mixed $responseMessage
205
     */
206
    public function setResponseMessage($responseMessage): void
207
    {
208
        $this->responseMessage = $responseMessage;
209
    }
210
211
    /**
212
     * @return Card
213
     */
214
    public function getCard()
215
    {
216
        return $this->card;
217
    }
218
219
    /**
220
     * @param Card $card
221
     */
222
    public function setCard($card): void
223
    {
224
        $this->card = $card;
225
    }
226
227
    public function isVaultTransaction()
228
    {
229
        if ($this->getCard() !== null) {
230
            return !empty($this->getCard()->getToken());
231
        }
232
233
        //TODO: Do the same for ACH Bank Account Token as well
234
        return false;
235
    }
236
237
    public function isCardTransaction()
238
    {
239
        return $this->getCard() !== null;
240
    }
241
242
    /**
243
     * @throws LogicException
244
     * @throws ClientException
245
     */
246
    public function authorize()
247
    {
248
        if ($this->isVaultTransaction()) {
249
            Helpers::validateArray($this->toAuthorizeTransactionArray(), ['bank_card_transaction_type', 'token', 'bank_card_transaction_amount']);
250
        } else {
251
            Helpers::validateArray($this->toAuthorizeTransactionArray(), [
252
                'bank_card_transaction_name', 'bank_card_transaction_card_number', 'bank_card_transaction_expiration_month',
253
                'bank_card_transaction_expiration_year', 'bank_card_transaction_type', 'bank_card_transaction_amount'
254
            ]);
255
        }
256
257
        return $this->processTransaction($this->toAuthorizeTransactionArray());
258
    }
259
260
    /**
261
     * @return $this
262
     * @throws ClientException
263
     * @throws LogicException
264
     */
265
    public function capture()
266
    {
267
        Helpers::validateArray($this->toCaptureTransactionArray(), ['bank_card_transaction_id', 'bank_card_transaction_amount', 'bank_card_transaction_type']);
268
269
        return $this->processTransaction($this->toCaptureTransactionArray());
270
    }
271
272
    /**
273
     * @throws LogicException
274
     * @throws ClientException
275
     */
276
    public function createSale()
277
    {
278
        if ($this->isVaultTransaction()) {
279
            Helpers::validateArray($this->toCreateTransactionArray(), ['bank_card_transaction_type', 'token', 'bank_card_transaction_amount']);
280
        } else {
281
            Helpers::validateArray($this->toCreateTransactionArray(), [
282
                'bank_card_transaction_name', 'bank_card_transaction_card_number', 'bank_card_transaction_expiration_month',
283
                'bank_card_transaction_expiration_year', 'bank_card_transaction_type', 'bank_card_transaction_amount'
284
            ]);
285
        }
286
287
        return $this->processTransaction($this->toCreateTransactionArray());
288
    }
289
290
    /**
291
     * @throws LogicException
292
     * @throws ClientException
293
     */
294
    public function refundSale()
295
    {
296
        Helpers::validateArray($this->toRefundTransactionArray(), ['bank_card_transaction_id', 'bank_card_transaction_amount', 'bank_card_transaction_type']);
297
298
        return $this->processTransaction($this->toRefundTransactionArray());
299
    }
300
301
    /**
302
     * @param $data
303
     * @return $this
304
     * @throws ClientException
305
     */
306
    private function processTransaction($data)
307
    {
308
        $response = $this->client->postRequest(self::URI_CARD_TRANSACTION, json_encode($data));
309
310
        $instance = $this->fromArray($response['bank_card_transaction']);
311
312
        $instance->handleMessages($response);
313
314
        return $instance;
315
    }
316
317
    /**
318
     * @return array
319
     */
320
    private function toRefundTransactionArray(): array
321
    {
322
        return clear_array([
323
            'bank_card_transaction_id' => $this->getTransactionId(),
324
            'bank_card_transaction_amount' => $this->getAmount(),
325
            'bank_card_transaction_type' => self::TRANSACTION_TYPE_REFUND
326
        ]);
327
    }
328
329
    private function toCaptureTransactionArray(): array
330
    {
331
        $data = $this->toRefundTransactionArray();
332
333
        array_set($data, 'bank_card_transaction_type', self::TRANSACTION_TYPE_CAPTURE);
334
335
        return $data;
336
    }
337
338
    /**
339
     * @return array
340
     * @throws LogicException
341
     */
342
    private function toCreateTransactionArray(): array
343
    {
344
        if ($this->isCardTransaction()) {
345
            if ($this->isVaultTransaction()) {
346
                return clear_array([
347
                    'bank_card_transaction_type' => self::TRANSACTION_TYPE_SALE,
348
                    'token' => $this->getCard()->getToken(),
349
                    'bank_card_transaction_amount' => $this->getAmount()
350
                ]);
351
            } else {
352
                return clear_array([
353
                    'bank_card_transaction_name' => $this->getCard()->getName(),
354
                    'bank_card_transaction_card_number' => $this->getCard()->getCardNumber(),
355
                    'bank_card_transaction_expiration_month' => $this->getCard()->getCardExpirationMonth(),
356
                    'bank_card_transaction_expiration_year' => $this->getCard()->getCardExpirationYear(),
357
                    'bank_card_transaction_billing_address' => $this->getCard()->getBillingAddress() ? $this->getCard()->getBillingAddress()->toArray() : null,
358
                    'bank_card_transaction_type' => self::TRANSACTION_TYPE_SALE,
359
                    'bank_card_transaction_amount' => $this->getAmount()
360
                ]);
361
            }
362
        } else {
363
            throw LogicException::pendingImplementation('ACH Bank Transaction implementation');
364
        }
365
    }
366
367
    /**
368
     * @return array
369
     * @throws LogicException
370
     */
371
    private function toAuthorizeTransactionArray(): array
372
    {
373
        if ($this->isCardTransaction()) {
374
            $data = $this->toCreateTransactionArray();
375
376
            array_set($data, 'bank_card_transaction_type', self::TRANSACTION_TYPE_AUTHORIZE);
377
378
            return $data;
379
        } else {
380
            throw LogicException::methodCallNotSupported('ACH Processing');
381
        }
382
    }
383
384
    private function fromArray(array $data)
385
    {
386
        $instance = new static();
387
388
        $instance->setTransactionId(array_get($data, 'bank_card_transaction_id'));
389
        $instance->setStatus(array_get($data, 'bank_card_transaction_status.bank_card_transaction_status_name'));
390
        $instance->setAmount(array_get($data, 'bank_card_transaction_amount', 0));
391
        $instance->setTipAmount(array_get($data, 'bank_card_transaction_tip_amount', 0));
392
        $instance->setTaxAmount(array_get($data, 'bank_card_transaction_tax_amount', 0));
393
        $instance->setAuthorizationDate(Carbon::parse(array_get($data, 'bank_card_transaction_authorization_date'))->toDateTime());
394
        $instance->setCapturedDate(Carbon::parse(array_get($data, 'bank_card_transaction_capture_date'))->toDateTime());
395
        $instance->setTransactionType(array_get($data, 'bank_card_transaction_type.bank_card_transaction_type_name'));
396
        $instance->setResponseCode(array_get($data, 'bank_card_transaction_response_code'));
397
        $instance->setResponseMessage(array_get($data, 'bank_card_transaction_response_message'));
398
399
        return $instance;
400
    }
401
}