Service::setTransaction()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
namespace Beelab\PaypalBundle\Paypal;
4
5
use Beelab\PaypalBundle\Entity\Transaction;
6
use Omnipay\PayPal\ExpressGateway as Gateway;
7
use RuntimeException;
8
use Symfony\Component\Routing\RouterInterface;
9
10
/**
11
 * Paypal service.
12
 */
13
class Service
14
{
15
    /**
16
     * @var Transaction
17
     */
18
    protected $transaction;
19
20
    /**
21
     * @var Gateway
22
     */
23
    private $gateway;
24
25
    /**
26
     * @var RouterInterface
27
     */
28
    private $router;
29
30
    /**
31
     * @var array
32
     */
33
    private $config;
34
35
    /**
36
     * @var array
37
     */
38
    private $params;
39
40
    /**
41
     * @param Gateway         $gateway
42
     * @param RouterInterface $router
43
     * @param array           $config
44
     */
45
    public function __construct(Gateway $gateway, RouterInterface $router, array $config)
46
    {
47
        $gateway
48
            ->setUsername($config['username'])
49
            ->setPassword($config['password'])
50
            ->setSignature($config['signature'])
51
            ->setTestMode($config['test_mode'])
52
        ;
53
        $this->gateway = $gateway;
54
        $this->config = $config;
55
        $this->router = $router;
56
    }
57
58
    /**
59
     * Set Transaction and parameters.
60
     *
61
     * @param Transaction $transaction
62
     * @param array       $customParameters
63
     *
64
     * @return Service
65
     */
66
    public function setTransaction(Transaction $transaction, array $customParameters = [])
67
    {
68
        $defaultParameters = [
69
            'amount' => $transaction->getAmount(),
70
            'currency' => $this->config['currency'],
71
            'description' => $transaction->getDescription(),
72
            'transactionId' => $transaction->getId(),
73
            'returnUrl' => $this->router->generate(
74
                $this->config['return_route'],
75
                [],
76
                RouterInterface::ABSOLUTE_URL
77
            ),
78
            'cancelUrl' => $this->router->generate(
79
                $this->config['cancel_route'],
80
                [],
81
                RouterInterface::ABSOLUTE_URL
82
            ),
83
        ];
84
        $this->params = \array_merge($defaultParameters, $customParameters);
85
        $this->transaction = $transaction;
86
        $items = $transaction->getItems();
87
        if (!empty($items)) {
88
            $this->params['shippingAmount'] = $transaction->getShippingAmount();
89
        }
90
91
        return $this;
92
    }
93
94
    /**
95
     * Start transaction. You need to call setTransaction() before.
96
     *
97
     * @return \Omnipay\Common\Message\ResponseInterface
98
     */
99
    public function start()
100
    {
101
        if (null === $this->transaction) {
102
            throw new RuntimeException('Transaction not defined. Call setTransaction() first.');
103
        }
104
        $items = $this->transaction->getItems();
105
        $purchase = $this->gateway->purchase($this->params);
106
        $response = !empty($items) ? $purchase->setItems($items)->send() : $purchase->send();
107
        if (!$response->isRedirect()) {
108
            throw new Exception($response->getMessage());
109
        }
110
        $this->transaction->setToken($response->getTransactionReference());
111
112
        return $response;
113
    }
114
115
    /**
116
     * Complete transaction. You need to call setTransaction() before.
117
     */
118
    public function complete(): void
119
    {
120
        if (null === $this->transaction) {
121
            throw new RuntimeException('Transaction not defined. Call setTransaction() first.');
122
        }
123
        $items = $this->transaction->getItems();
124
        $purchase = $this->gateway->completePurchase($this->params);
125
        $response = !empty($items) ? $purchase->setItems($items)->send() : $purchase->send();
126
        $responseData = $response->getData();
127
        if (!isset($responseData['ACK'])) {
128
            throw new RuntimeException('Missing ACK Payapl in response data.');
129
        }
130
        if ('Success' != $responseData['ACK'] && 'SuccessWithWarning' != $responseData['ACK']) {
131
            $this->transaction->error($responseData);
132
        } else {
133
            $this->transaction->complete($responseData);
134
        }
135
    }
136
}
137