PaymentStateResolver   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 37
c 1
b 0
f 0
dl 0
loc 78
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A applyTransition() 0 4 2
A resolveState() 0 27 6
A resolve() 0 22 3
1
<?php
2
3
/*
4
 * This file was created by developers working at BitBag
5
 * Do you need more information about us and what we do? Visit our https://bitbag.io website!
6
 * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
7
*/
8
9
declare(strict_types=1);
10
11
namespace BitBag\SyliusCoinbasePlugin\Resolver;
12
13
use BitBag\SyliusCoinbasePlugin\ApiClient\CoinbaseApiClientInterface;
14
use BitBag\SyliusCoinbasePlugin\CoinbaseGatewayFactory;
15
use CoinbaseCommerce\Resources\Charge;
16
use Doctrine\ORM\EntityManagerInterface;
17
use SM\Factory\FactoryInterface;
18
use SM\StateMachine\StateMachineInterface;
19
use Sylius\Component\Core\Model\PaymentInterface;
20
use Sylius\Component\Core\Model\PaymentMethodInterface;
21
use Sylius\Component\Payment\PaymentTransitions;
22
23
final class PaymentStateResolver implements PaymentStateResolverInterface
24
{
25
    /** @var FactoryInterface */
26
    private $stateMachineFactory;
27
28
    /** @var CoinbaseApiClientInterface */
29
    private $coinbaseApiClient;
30
31
    /** @var EntityManagerInterface */
32
    private $paymentEntityManager;
33
34
    public function __construct(
35
        FactoryInterface $stateMachineFactory,
36
        CoinbaseApiClientInterface $coinbaseApiClient,
37
        EntityManagerInterface $paymentEntityManager
38
    ) {
39
        $this->stateMachineFactory = $stateMachineFactory;
40
        $this->coinbaseApiClient = $coinbaseApiClient;
41
        $this->paymentEntityManager = $paymentEntityManager;
42
    }
43
44
    public function resolve(PaymentInterface $payment): void
45
    {
46
        /** @var PaymentMethodInterface $paymentMethod */
47
        $paymentMethod = $payment->getMethod();
48
49
        if (CoinbaseGatewayFactory::FACTORY_NAME !== $paymentMethod->getGatewayConfig()->getConfig()['factoryName']) {
50
            return;
51
        }
52
53
        $details = $payment->getDetails();
54
55
        if (!isset($details['payment_id'])) {
56
            return;
57
        }
58
59
        $gatewayConfig = $paymentMethod->getGatewayConfig()->getConfig();
60
61
        $this->coinbaseApiClient->initialise($gatewayConfig['apiKey']);
62
63
        $charge = $this->coinbaseApiClient->show($details['payment_id']);
64
65
        $this->resolveState($payment, $charge);
66
    }
67
68
    private function resolveState(PaymentInterface $payment, Charge $charge): void
69
    {
70
        $paymentStateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH);
71
72
        $timeline = (array)$charge->timeline;
73
        $timelineLast = end($timeline);
74
75
        switch (strtolower($timelineLast['status'])) {
76
            case CoinbaseApiClientInterface::STATUS_CANCELED:
77
                $this->applyTransition($paymentStateMachine, PaymentTransitions::TRANSITION_CANCEL);
78
79
                break;
80
            case CoinbaseApiClientInterface::STATUS_COMPLETED:
81
                $this->applyTransition($paymentStateMachine, PaymentTransitions::TRANSITION_COMPLETE);
82
83
                break;
84
            case CoinbaseApiClientInterface::STATUS_PENDING:
85
            case CoinbaseApiClientInterface::STATUS_CREATED:
86
            case CoinbaseApiClientInterface::STATUS_NEW:
87
                $this->applyTransition($paymentStateMachine, PaymentTransitions::TRANSITION_PROCESS);
88
89
                break;
90
            default:
91
                $this->applyTransition($paymentStateMachine, PaymentTransitions::TRANSITION_FAIL);
92
        }
93
94
        $this->paymentEntityManager->flush();
95
    }
96
97
    private function applyTransition(StateMachineInterface $paymentStateMachine, string $transition): void
98
    {
99
        if ($paymentStateMachine->can($transition)) {
100
            $paymentStateMachine->apply($transition);
101
        }
102
    }
103
}
104