CaptureResponse   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 73
c 1
b 0
f 1
dl 0
loc 183
rs 9.92
wmc 31

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getMerchantData() 0 3 1
A getKey() 0 7 3
A getCode() 0 9 2
A getCardCountry() 0 3 1
A getTransactionReference() 0 3 1
C __construct() 0 74 14
A getMessage() 0 9 2
B isSuccessful() 0 14 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Omnipay\Redsys\Message;
6
7
use AvaiBookSports\Component\RedsysMessages\Exception\CatalogNotFoundException;
8
use AvaiBookSports\Component\RedsysMessages\Factory;
9
use AvaiBookSports\Component\RedsysMessages\Loader\CatalogLoader;
10
use Http\Discovery\MessageFactoryDiscovery;
11
use Omnipay\Common\Exception\InvalidResponseException;
12
use Omnipay\Common\Http\Exception\RequestException;
13
use Omnipay\Common\Message\RequestInterface;
14
15
class CaptureResponse extends AbstractResponse
16
{
17
    protected $returnSignature;
18
19
    /** @var bool */
20
    protected $usingUpcaseResponse = false;
21
22
    /** @var CatalogInterface */
0 ignored issues
show
Bug introduced by
The type Omnipay\Redsys\Message\CatalogInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
    protected $redsysMessages;
24
25
    public function __construct(RequestInterface $request, $data)
26
    {
27
        parent::__construct($request, $data);
28
29
        $security = new Security();
30
31
        try {
32
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage(array_key_exists('language', $this->request->getParameters()) ? $this->request->getParameters()['language'] : 'en');
0 ignored issues
show
Documentation Bug introduced by
It seems like new AvaiBookSports\Compo...s()['language'] : 'en') of type AvaiBookSports\Component...ssages\CatalogInterface is incompatible with the declared type Omnipay\Redsys\Message\CatalogInterface of property $redsysMessages.

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...
33
        } catch (CatalogNotFoundException $e) {
34
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
35
        }
36
37
        if (!isset($data['CODIGO'])) {
38
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
39
        }
40
41
        if (!isset($data['OPERACION'])) {
42
            if ('0' == $data['CODIGO']) {
43
                throw new InvalidResponseException('Invalid response from payment gateway (no data)');
44
            }
45
        }
46
47
        // Exceeder API rate limit
48
        if ('SIS0295' == $data['CODIGO'] || '9295' == $data['CODIGO']) {
49
            throw new RequestException('Too many requests. "'.$data['CODIGO'].'"', MessageFactoryDiscovery::find()->createRequest('POST', $this->getRequest()->getEndpoint(), ['SOAPAction' => 'trataPeticion']));
0 ignored issues
show
Bug introduced by
The method getEndpoint() does not exist on Omnipay\Common\Message\RequestInterface. It seems like you code against a sub-type of Omnipay\Common\Message\RequestInterface such as Omnipay\Redsys\Message\AbstractRequest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
            throw new RequestException('Too many requests. "'.$data['CODIGO'].'"', MessageFactoryDiscovery::find()->createRequest('POST', $this->getRequest()->/** @scrutinizer ignore-call */ getEndpoint(), ['SOAPAction' => 'trataPeticion']));
Loading history...
50
        }
51
52
        if (isset($data['OPERACION']['DS_ORDER'])) {
53
            $this->usingUpcaseResponse = true;
54
        }
55
56
57
58
        if (!empty($data['OPERACION'])) {
59
            if (!empty($data['OPERACION']['Ds_CardNumber'])) {
60
                $signature_keys = [
61
                    'Ds_Amount',
62
                    'Ds_Order',
63
                    'Ds_MerchantCode',
64
                    'Ds_Currency',
65
                    'Ds_Response',
66
                    'Ds_CardNumber',
67
                    'Ds_TransactionType',
68
                    'Ds_SecurePayment',
69
                ];
70
            } else {
71
                $signature_keys = [
72
                    'Ds_Amount',
73
                    'Ds_Order',
74
                    'Ds_MerchantCode',
75
                    'Ds_Currency',
76
                    'Ds_Response',
77
                    'Ds_TransactionType',
78
                    'Ds_SecurePayment',
79
                ];
80
            }
81
82
            $signature_data = '';
83
            foreach ($signature_keys as $key) {
84
                $value = $this->getKey($key);
85
                if (null === $value) {
86
                    throw new InvalidResponseException('Invalid response from payment gateway (missing data)');
87
                }
88
                $signature_data .= $value;
89
            }
90
91
            $this->returnSignature = $security->createSignature(
92
                $signature_data,
93
                $this->getKey('Ds_Order'),
94
                $this->request->getHmacKey()
0 ignored issues
show
Bug introduced by
The method getHmacKey() does not exist on Omnipay\Common\Message\RequestInterface. It seems like you code against a sub-type of Omnipay\Common\Message\RequestInterface such as Omnipay\Redsys\Message\AbstractRequest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

94
                $this->request->/** @scrutinizer ignore-call */ 
95
                                getHmacKey()
Loading history...
95
            );
96
97
            if ($this->returnSignature != $this->getKey('Ds_Signature')) {
98
                throw new InvalidResponseException('Invalid response from payment gateway (signature mismatch)');
99
            }
100
        }
101
    }
102
103
    /**
104
     * @return bool
105
     */
106
    public function isSuccessful()
107
    {
108
        $response_code = $this->getKey('Ds_Response');
109
110
        if (isset($this->data['CODIGO']) && 'SIS0060' === $this->data['CODIGO']) {
111
            return true;
112
        }
113
114
        // check for field existence as well as value
115
        return isset($this->data['CODIGO'])
116
            && '0' == $this->data['CODIGO']
117
            && null !== $response_code
118
            && is_numeric($response_code)
119
            && 900 == $response_code;
120
    }
121
122
    /**
123
     * Helper method to get a specific response parameter if available.
124
     *
125
     * @param string $key The key to look up
126
     *
127
     * @return mixed|null
128
     */
129
    protected function getKey($key)
130
    {
131
        if ($this->usingUpcaseResponse) {
132
            $key = strtoupper($key);
133
        }
134
135
        return isset($this->data['OPERACION'][$key]) ? $this->data['OPERACION'][$key] : null;
136
    }
137
138
    /**
139
     * Get the authorisation code if available.
140
     *
141
     * @return string|null
142
     */
143
    public function getTransactionReference()
144
    {
145
        return $this->getAuthorisationCode() ?? $this->request->getParameters()['transactionId'];
146
    }
147
148
    /**
149
     * Get the merchant message if available.
150
     *
151
     * @return string|null A response message from the payment gateway
152
     */
153
    public function getMessage()
154
    {
155
        $message = $this->redsysMessages->getDsResponseMessage($this->getCode());
156
157
        if (null === $message) {
158
            $message = $this->redsysMessages->getErrorMessage($this->getCode());
159
        }
160
161
        return $message;
162
    }
163
164
    /**
165
     * Get the merchant response code if available.
166
     *
167
     * @return string|null
168
     */
169
    public function getCode()
170
    {
171
        $code = $this->getKey('Ds_Response');
172
173
        if (null === $code) {
174
            $code = $this->data['CODIGO'];
175
        }
176
177
        return $code;
178
    }
179
180
    /**
181
     * Get the merchant data if available.
182
     *
183
     * @return string|null
184
     */
185
    public function getMerchantData()
186
    {
187
        return $this->getKey('Ds_MerchantData');
188
    }
189
190
    /**
191
     * Get the card country if available.
192
     *
193
     * @return string|null ISO 3166-1 (3-digit numeric) format, if supplied
194
     */
195
    public function getCardCountry()
196
    {
197
        return $this->getKey('Ds_Card_Country');
198
    }
199
}
200