Passed
Push — master ( 669a46...82dcb0 )
by
unknown
10:39 queued 48s
created

CaptureResponse::isSuccessful()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 8
c 1
b 0
f 1
nc 6
nop 0
dl 0
loc 14
rs 8.8333
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\AbstractResponse;
14
use Omnipay\Common\Message\RequestInterface;
15
16
class CaptureResponse extends AbstractResponse
17
{
18
    protected $returnSignature;
19
20
    /** @var bool */
21
    protected $usingUpcaseResponse = false;
22
23
    /** @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...
24
    protected $redsysMessages;
25
26
    public function __construct(RequestInterface $request, $data)
27
    {
28
        parent::__construct($request, $data);
29
30
        $security = new Security();
31
32
        try {
33
            $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...
34
        } catch (CatalogNotFoundException $e) {
35
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
36
        }
37
38
        if (!isset($data['CODIGO'])) {
39
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
40
        }
41
42
        if (!isset($data['OPERACION'])) {
43
            if ('0' == $data['CODIGO']) {
44
                throw new InvalidResponseException('Invalid response from payment gateway (no data)');
45
            }
46
        }
47
48
        // Exceeder API rate limit
49
        if ('SIS0295' == $data['CODIGO'] || '9295' == $data['CODIGO']) {
50
            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

50
            throw new RequestException('Too many requests. "'.$data['CODIGO'].'"', MessageFactoryDiscovery::find()->createRequest('POST', $this->getRequest()->/** @scrutinizer ignore-call */ getEndpoint(), ['SOAPAction' => 'trataPeticion']));
Loading history...
51
        }
52
53
        if (isset($data['OPERACION']['DS_ORDER'])) {
54
            $this->usingUpcaseResponse = true;
55
        }
56
57
58
59
        if (!empty($data['OPERACION'])) {
60
            if (!empty($data['OPERACION']['Ds_CardNumber'])) {
61
                $signature_keys = [
62
                    'Ds_Amount',
63
                    'Ds_Order',
64
                    'Ds_MerchantCode',
65
                    'Ds_Currency',
66
                    'Ds_Response',
67
                    'Ds_CardNumber',
68
                    'Ds_TransactionType',
69
                    'Ds_SecurePayment',
70
                ];
71
            } else {
72
                $signature_keys = [
73
                    'Ds_Amount',
74
                    'Ds_Order',
75
                    'Ds_MerchantCode',
76
                    'Ds_Currency',
77
                    'Ds_Response',
78
                    'Ds_TransactionType',
79
                    'Ds_SecurePayment',
80
                ];
81
            }
82
83
            $signature_data = '';
84
            foreach ($signature_keys as $key) {
85
                $value = $this->getKey($key);
86
                if (null === $value) {
87
                    throw new InvalidResponseException('Invalid response from payment gateway (missing data)');
88
                }
89
                $signature_data .= $value;
90
            }
91
92
            $this->returnSignature = $security->createSignature(
93
                $signature_data,
94
                $this->getKey('Ds_Order'),
95
                $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

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