Completed
Push — master ( 1f0278...22c246 )
by
unknown
12s
created

Payment   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 664
Duplicated Lines 3.31 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 22
loc 664
rs 8.1838
c 0
b 0
f 0
wmc 47
lcom 1
cbo 6

37 Methods

Rating   Name   Duplication   Size   Complexity  
A initialize() 0 6 1
A execute() 0 12 2
A get() 0 8 2
A getId() 0 4 1
A populate() 0 22 1
A refunds() 0 7 1
A escrows() 0 7 1
A getStatus() 0 4 1
A getCreatedAt() 0 4 1
A getUpdatedAt() 0 4 1
A getFundingInstrument() 0 5 1
A getHrefBoleto() 0 4 1
A getLineCodeBoleto() 0 4 1
A getHrefPrintBoleto() 0 4 1
A getExpirationDateBoleto() 0 4 1
A getAmount() 0 4 1
A getEscrow() 0 4 1
A getInstallmentCount() 0 4 1
A getPayments() 0 4 1
A setFundingInstrument() 0 6 1
A setBoleto() 0 21 3
A setCreditCardHolder() 0 18 2
A setCreditCardHash() 0 10 1
A setCreditCard() 0 13 1
A setCreditCardSaved() 0 10 1
A setInstallmentCount() 0 6 1
A setStatementDescriptor() 0 6 1
A setOnlineBankDebit() 0 13 2
A setMultiorder() 0 6 1
A setOrder() 0 6 1
A setDelayCapture() 0 6 1
A setEscrow() 0 7 1
A capture() 11 11 2
A cancel() 11 11 2
A avoid() 0 6 1
A authorize() 0 14 3
A isMultipayment() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Payment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Payment, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Moip\Resource;
4
5
use Requests;
6
use stdClass;
7
8
/**
9
 * Class Payment.
10
 */
11
class Payment extends MoipResource
12
{
13
    /**
14
     * @const string
15
     */
16
    const PATH = 'payments';
17
18
    /**
19
     * @const string
20
     */
21
    const MULTI_PAYMENTS_PATH = 'multipayments';
22
23
    /**
24
     * @const string
25
     */
26
    const SIMULATOR_PATH = 'simulador';
27
28
    /**
29
     * Payment means.
30
     *
31
     * @const string
32
     */
33
    const METHOD_CREDIT_CARD = 'CREDIT_CARD';
34
35
    /**
36
     * Payment means.
37
     *
38
     * @const string
39
     */
40
    const METHOD_BOLETO = 'BOLETO';
41
42
    /**
43
     * Payment means.
44
     *
45
     * @const string
46
     */
47
    const METHOD_ONLINE_DEBIT = 'ONLINE_DEBIT';
48
49
    /**
50
     * Payment means.
51
     *
52
     * @const string
53
     */
54
    const METHOD_WALLET = 'WALLET';
55
56
    /**
57
     * Payment means.
58
     *
59
     * @const string
60
     */
61
    const METHOD_ONLINE_BANK_DEBIT = 'ONLINE_BANK_DEBIT';
62
63
    /**
64
     * @var \Moip\Resource\Orders
65
     */
66
    private $order;
67
68
    /**
69
     * Just created, but not initialized yet.
70
     */
71
    const STATUS_CREATED = 'CREATED';
72
73
    /**
74
     * Waiting for the payment.
75
     */
76
    const STATUS_WAITING = 'WAITING';
77
78
    /**
79
     * On risk analysis, it may be automatic or manual.
80
     */
81
    const STATUS_IN_ANALYSIS = 'IN_ANALYSIS';
82
83
    /**
84
     * The amount was reserved on client credit card, it may be caught or discarded until 5 days.
85
     */
86
    const STATUS_PRE_AUTHORIZED = 'PRE_AUTHORIZED';
87
88
    /**
89
     * Payment confirmed by the bank institution.
90
     */
91
    const STATUS_AUTHORIZED = 'AUTHORIZED';
92
93
    /**
94
     * Payment cancelled.
95
     */
96
    const STATUS_CANCELLED = 'CANCELLED';
97
98
    /**
99
     * Payment refunded.
100
     */
101
    const STATUS_REFUNDED = 'REFUNDED';
102
103
    /**
104
     * Paymend reversed (it means that the payment may was not recognized by the client).
105
     */
106
    const STATUS_REVERSED = 'REVERSED';
107
108
    /**
109
     * Payment finalized, the amout is on your account.
110
     */
111
    const STATUS_SETTLED = 'SETTLED';
112
113
    /**
114
     * @var \Moip\Resource\Multiorders
115
     */
116
    private $multiorder;
117
118
    /**
119
     * Initializes new instances.
120
     */
121
    protected function initialize()
122
    {
123
        $this->data = new stdClass();
124
        $this->data->installmentCount = 1;
125
        $this->data->fundingInstrument = new stdClass();
126
    }
127
128
    /**
129
     * Create a new payment in api MoIP.
130
     *
131
     * @return $this
132
     */
133
    public function execute()
134
    {
135
        if ($this->order !== null) {
136
            $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, Orders::PATH, $this->order->getId(), self::PATH);
137
        } else {
138
            $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, Multiorders::PATH, $this->multiorder->getId(), self::MULTI_PAYMENTS_PATH);
139
        }
140
141
        $response = $this->httpRequest($path, Requests::POST, $this);
142
143
        return $this->populate($response);
144
    }
145
146
    /**
147
     * Get an payment and multipayment in MoIP.
148
     *
149
     * @param string $id_moip Id MoIP payment
150
     *
151
     * @return stdClass
152
     */
153
    public function get($id_moip)
154
    {
155
        if ($this->isMultipayment($id_moip)) {
156
            return $this->getByPath(sprintf('/%s/%s/%s', MoipResource::VERSION, self::MULTI_PAYMENTS_PATH, $id_moip));
157
        }
158
159
        return $this->getByPath(sprintf('/%s/%s/%s', MoipResource::VERSION, self::PATH, $id_moip));
160
    }
161
162
    /**
163
     * Get id MoIP payment.
164
     *
165
     *
166
     * @return \Moip\Resource\Payment
167
     */
168
    public function getId()
169
    {
170
        return $this->getIfSet('id');
171
    }
172
173
    /**
174
     * Mount payment structure.
175
     *
176
     * @param \stdClass $response
177
     *
178
     * @return Payment
179
     */
180
    protected function populate(stdClass $response)
181
    {
182
        $payment = clone $this;
183
184
        $payment->data->id = $this->getIfSet('id', $response);
185
        $payment->data->status = $this->getIfSet('status', $response);
186
        $payment->data->delayCapture = $this->getIfSet('delayCapture', $response);
187
        $payment->data->amount = new stdClass();
188
        $payment->data->amount->total = $this->getIfSet('total', $response->amount);
189
        $payment->data->amount->currency = $this->getIfSet('currency', $response->amount);
190
        $payment->data->installmentCount = $this->getIfSet('installmentCount', $response);
191
        $payment->data->fundingInstrument = $this->getIfSet('fundingInstrument', $response);
192
        $payment->data->payments = $this->getIfSet('payments', $response);
193
        $payment->data->escrows = $this->getIfSet('escrows', $response);
194
        $payment->data->fees = $this->getIfSet('fees', $response);
195
        $payment->data->refunds = $this->getIfSet('refunds', $response);
196
        $payment->data->_links = $this->getIfSet('_links', $response);
197
        $payment->data->createdAt = $this->getIfSetDateTime('createdAt', $response);
198
        $payment->data->updatedAt = $this->getIfSetDateTime('updatedAt', $response);
199
200
        return $payment;
201
    }
202
203
    /**
204
     * Refunds.
205
     *
206
     * @return Refund
207
     */
208
    public function refunds()
209
    {
210
        $refund = new Refund($this->moip);
211
        $refund->setPayment($this);
212
213
        return $refund;
214
    }
215
216
    /**
217
     * Escrows.
218
     *
219
     * @return Escrow
220
     */
221
    public function escrows()
222
    {
223
        $escrow = new Escrow($this->moip);
224
        $escrow->setId($this->getEscrow()->id);
225
226
        return $escrow;
227
    }
228
229
    /**
230
     * Get payment status.
231
     *
232
     * @return string Payment status. Possible values CREATED, WAITING, IN_ANALYSIS, PRE_AUTHORIZED, AUTHORIZED, CANCELLED, REFUNDED, REVERSED, SETTLED
233
     */
234
    public function getStatus()
235
    {
236
        return $this->getIfSet('status');
237
    }
238
239
    /**
240
     * get creation time.
241
     *
242
     * @return \DateTime
243
     */
244
    public function getCreatedAt()
245
    {
246
        return $this->data->createdAt;
247
    }
248
249
    /**
250
     * Returns when the last update occurred.
251
     *
252
     * @return \DateTime
253
     */
254
    public function getUpdatedAt()
255
    {
256
        return $this->data->updatedAt;
257
    }
258
259
    /**
260
     * Returns the funding instrument.
261
     *
262
     * @return stdClass
263
     */
264
    public function getFundingInstrument()
265
    {
266
        //todo: return a funding instrument object
267
        return $this->data->fundingInstrument;
268
    }
269
270
    /**
271
     * Get href to Boleto
272
     * *.
273
     *
274
     * @return stdClass
275
     */
276
    public function getHrefBoleto()
277
    {
278
        return $this->getIfSet('_links')->payBoleto->redirectHref;
279
    }
280
281
    /**
282
     * Get LineCode to Boleto
283
     * *.
284
     *
285
     * @return stdClass
286
     */
287
    public function getLineCodeBoleto()
288
    {
289
        return $this->getIfSet('fundingInstrument')->boleto->lineCode;
290
    }
291
292
    /**
293
     * Get href from print to Boleto
294
     * *.
295
     *
296
     * @return stdClass
297
     */
298
    public function getHrefPrintBoleto()
299
    {
300
        return $this->getIfSet('_links')->payBoleto->printHref;
301
    }
302
303
    /**
304
     * Get Expirate Date to Boleto
305
     * *.
306
     *
307
     * @return stdClass
308
     */
309
    public function getExpirationDateBoleto()
310
    {
311
        return $this->getIfSet('fundingInstrument')->boleto->expirationDate;
312
    }
313
314
    /**
315
     * Returns payment amount.
316
     *
317
     * @return stdClass
318
     */
319
    public function getAmount()
320
    {
321
        return $this->data->amount;
322
    }
323
324
    /**
325
     * Returns escrow.
326
     *
327
     * @return stdClass
328
     */
329
    public function getEscrow()
330
    {
331
        return reset($this->data->escrows);
332
    }
333
334
    /**
335
     * Returns installment count.
336
     *
337
     * @return stdClass
338
     */
339
    public function getInstallmentCount()
340
    {
341
        return $this->data->installmentCount;
342
    }
343
344
    /**
345
     * Get payments.
346
     *
347
     * @return array
348
     */
349
    public function getPayments()
350
    {
351
        return $this->getIfSet('payments');
352
    }
353
354
    /**
355
     * Set means of payment.
356
     *
357
     * @param \stdClass $fundingInstrument
358
     *
359
     * @return $this
360
     */
361
    public function setFundingInstrument(stdClass $fundingInstrument)
362
    {
363
        $this->data->fundingInstrument = $fundingInstrument;
364
365
        return $this;
366
    }
367
368
    /**
369
     * Set billet.
370
     *
371
     * @param \DateTime|string $expirationDate   Expiration date of a billet.
372
     * @param string           $logoUri          Logo of billet.
373
     * @param array            $instructionLines Instructions billet.
374
     *
375
     * @return $this
376
     */
377
    public function setBoleto($expirationDate, $logoUri, array $instructionLines = [])
378
    {
379
        $keys = ['first', 'second', 'third'];
380
381
        if (empty($instructionLines)) {
382
            //Avoid warning in array_combine
383
            $instructionLines = ['', '', ''];
384
        }
385
386
        if ($expirationDate instanceof \DateTime) {
387
            $expirationDate = $expirationDate->format('Y-m-d');
388
        }
389
390
        $this->data->fundingInstrument->method = self::METHOD_BOLETO;
391
        $this->data->fundingInstrument->boleto = new stdClass();
392
        $this->data->fundingInstrument->boleto->expirationDate = $expirationDate;
393
        $this->data->fundingInstrument->boleto->instructionLines = array_combine($keys, $instructionLines);
394
        $this->data->fundingInstrument->boleto->logoUri = $logoUri;
395
396
        return $this;
397
    }
398
399
    /**
400
     * Set credit card holder.
401
     *
402
     * @param \Moip\Resource\Customer $holder
403
     */
404
    private function setCreditCardHolder(Customer $holder)
405
    {
406
        $birthdate = $holder->getBirthDate();
407
        if ($birthdate instanceof \DateTime) {
408
            $birthdate = $birthdate->format('Y-m-d');
409
        }
410
        $this->data->fundingInstrument->creditCard->holder = new stdClass();
411
        $this->data->fundingInstrument->creditCard->holder->fullname = $holder->getFullname();
412
        $this->data->fundingInstrument->creditCard->holder->birthdate = $birthdate;
413
        $this->data->fundingInstrument->creditCard->holder->taxDocument = new stdClass();
414
        $this->data->fundingInstrument->creditCard->holder->taxDocument->type = $holder->getTaxDocumentType();
415
        $this->data->fundingInstrument->creditCard->holder->taxDocument->number = $holder->getTaxDocumentNumber();
416
        $this->data->fundingInstrument->creditCard->holder->phone = new stdClass();
417
        $this->data->fundingInstrument->creditCard->holder->phone->countryCode = $holder->getPhoneCountryCode();
418
        $this->data->fundingInstrument->creditCard->holder->phone->areaCode = $holder->getPhoneAreaCode();
419
        $this->data->fundingInstrument->creditCard->holder->phone->number = $holder->getPhoneNumber();
420
        $this->data->fundingInstrument->creditCard->holder->billingAddress = $holder->getBillingAddress();
421
    }
422
423
    /**
424
     * Set credit cardHash.
425
     *
426
     * @param string                  $hash   Credit card hash encripted using Moip.js
427
     * @param \Moip\Resource\Customer $holder
428
     * @param bool                    $store  Flag to know if credit card should be saved.
429
     *
430
     * @return $this
431
     */
432
    public function setCreditCardHash($hash, Customer $holder, $store = true)
433
    {
434
        $this->data->fundingInstrument->method = self::METHOD_CREDIT_CARD;
435
        $this->data->fundingInstrument->creditCard = new stdClass();
436
        $this->data->fundingInstrument->creditCard->hash = $hash;
437
        $this->data->fundingInstrument->creditCard->store = $store;
438
        $this->setCreditCardHolder($holder);
439
440
        return $this;
441
    }
442
443
    /**
444
     * Set credit card
445
     * Credit card used in a payment.
446
     * The card when returned within a parent resource is presented in its minimum representation.
447
     *
448
     * @param int                     $expirationMonth Card expiration month
449
     * @param int                     $expirationYear  Year of card expiration.
450
     * @param string                  $number          Card number.
451
     * @param int                     $cvc             Card Security Code.
452
     * @param \Moip\Resource\Customer $holder
453
     * @param bool                    $store           Flag to know if credit card should be saved.
454
     *
455
     * @return $this
456
     */
457
    public function setCreditCard($expirationMonth, $expirationYear, $number, $cvc, Customer $holder, $store = true)
458
    {
459
        $this->data->fundingInstrument->method = self::METHOD_CREDIT_CARD;
460
        $this->data->fundingInstrument->creditCard = new stdClass();
461
        $this->data->fundingInstrument->creditCard->expirationMonth = $expirationMonth;
462
        $this->data->fundingInstrument->creditCard->expirationYear = $expirationYear;
463
        $this->data->fundingInstrument->creditCard->number = $number;
464
        $this->data->fundingInstrument->creditCard->cvc = $cvc;
465
        $this->data->fundingInstrument->creditCard->store = $store;
466
        $this->setCreditCardHolder($holder);
467
468
        return $this;
469
    }
470
471
    /**
472
     * Sets data from a previously saved credit card
473
     * Credit card used in a payment.
474
     * Used when the credit card was saved with the customer and the payment made in a future date.
475
     *
476
     * @param string $creditCardId MoIP's Credit Card Id.
477
     * @param int    $cvc          Card Security Code.
478
     *
479
     * @return $this
480
     */
481
    public function setCreditCardSaved($creditCardId, $cvc)
482
    {
483
        $this->data->fundingInstrument = new stdClass();
484
        $this->data->fundingInstrument->method = self::METHOD_CREDIT_CARD;
485
        $this->data->fundingInstrument->creditCard = new stdClass();
486
        $this->data->fundingInstrument->creditCard->id = $creditCardId;
487
        $this->data->fundingInstrument->creditCard->cvc = $cvc;
488
489
        return $this;
490
    }
491
492
    /**
493
     * Set installment count.
494
     *
495
     * @param int $installmentCount
496
     *
497
     * @return $this
498
     */
499
    public function setInstallmentCount($installmentCount)
500
    {
501
        $this->data->installmentCount = $installmentCount;
502
503
        return $this;
504
    }
505
506
    /**
507
     * Set statement descriptor.
508
     *
509
     * @param string $statementDescriptor
510
     *
511
     * @return $this
512
     */
513
    public function setStatementDescriptor($statementDescriptor)
514
    {
515
        $this->data->statementDescriptor = $statementDescriptor;
516
517
        return $this;
518
    }
519
520
    /**
521
     * Set payment means made available by banks.
522
     *
523
     * @param string           $bankNumber     Bank number. Possible values: 001, 237, 341, 041.
524
     * @param \DateTime|string $expirationDate Date of expiration debit.
525
     * @param string           $returnUri      Return Uri.
526
     *
527
     * @return $this
528
     */
529
    public function setOnlineBankDebit($bankNumber, $expirationDate, $returnUri)
530
    {
531
        if ($expirationDate instanceof \DateTime) {
532
            $expirationDate = $expirationDate->format('Y-m-d');
533
        }
534
        $this->data->fundingInstrument->method = self::METHOD_ONLINE_BANK_DEBIT;
535
        $this->data->fundingInstrument->onlineBankDebit = new stdClass();
536
        $this->data->fundingInstrument->onlineBankDebit->bankNumber = $bankNumber;
537
        $this->data->fundingInstrument->onlineBankDebit->expirationDate = $expirationDate;
538
        $this->data->fundingInstrument->onlineBankDebit->returnUri = $returnUri;
539
540
        return $this;
541
    }
542
543
    /**
544
     * Set Multiorders.
545
     *
546
     * @param \Moip\Resource\Multiorders $multiorder
547
     *
548
     * @return $this
549
     */
550
    public function setMultiorder(Multiorders $multiorder)
551
    {
552
        $this->multiorder = $multiorder;
553
554
        return $this;
555
    }
556
557
    /**
558
     * Set order.
559
     *
560
     * @param \Moip\Resource\Orders $order
561
     *
562
     * @return $this
563
     */
564
    public function setOrder(Orders $order)
565
    {
566
        $this->order = $order;
567
568
        return $this;
569
    }
570
571
    /**
572
     * Turns on a delay on credit card payment capture (pre-authorization).
573
     *
574
     * @return $this
575
     */
576
    public function setDelayCapture()
577
    {
578
        $this->data->delayCapture = true;
579
580
        return $this;
581
    }
582
583
    /**
584
     * Set escrow to a payment.
585
     *
586
     * @param string $description
587
     *
588
     * @return $this
589
     */
590
    public function setEscrow($description)
591
    {
592
        $this->data->escrow = new stdClass();
593
        $this->data->escrow->description = $description;
594
595
        return $this;
596
    }
597
598
    /**
599
     * Capture a pre-authorized amount on a credit card payment.
600
     *
601
     * @throws \Exception
602
     *
603
     * @return Payment
604
     */
605 View Code Duplication
    public function capture()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
606
    {
607
        $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, self::PATH, $this->getId(), 'capture');
608
        if ($this->isMultipayment($this->getId())) {
609
            $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, self::MULTI_PAYMENTS_PATH, $this->getId(), 'capture');
610
        }
611
612
        $response = $this->httpRequest($path, Requests::POST, $this);
613
614
        return $this->populate($response);
615
    }
616
617
    /**
618
     * Cancel a pre-authorized amount on a credit card payment.
619
     *
620
     * @throws \Exception
621
     *
622
     * @return Payment
623
     */
624 View Code Duplication
    public function cancel()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
625
    {
626
        $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, self::PATH, $this->getId(), 'void');
627
        if ($this->isMultipayment($this->getId())) {
628
            $path = sprintf('/%s/%s/%s/%s', MoipResource::VERSION, self::MULTI_PAYMENTS_PATH, $this->getId(), 'void');
629
        }
630
631
        $response = $this->httpRequest($path, Requests::POST, $this);
632
633
        return $this->populate($response);
634
    }
635
636
    /**
637
     * Cancel a pre-authorized amount on a credit card payment.
638
     *
639
     * @throws \Exception
640
     *
641
     * @return Payment
642
     */
643
    public function avoid()
644
    {
645
        trigger_error('The function \'avoid\' is deprecated, use \'cancel\' instead', E_USER_NOTICE);
646
647
        return $this->cancel();
648
    }
649
650
    /**
651
     * Authorize a payment (Available only in sandbox to credit card payment with status IN_ANALYSIS and billet payment with status WAITING).
652
     *
653
     * @return bool
654
     */
655
    public function authorize($amount = null)
656
    {
657
        if (is_null($amount)) {
658
            $amount = $this->getAmount()->total;
659
        }
660
        $path = sprintf('/%s/%s?payment_id=%s&amount=%s', self::SIMULATOR_PATH, 'authorize', $this->getId(), $amount);
661
        $response = $this->httpRequest($path, Requests::GET);
662
663
        if (empty($response)) {
664
            return true;
665
        }
666
667
        return false;
668
    }
669
670
    private function isMultipayment($paymentId)
671
    {
672
        return 0 === strpos($paymentId, 'MPY');
673
    }
674
}
675