Passed
Push — master ( aa1475...13b16c )
by Pablo
11:39
created

RefundResponse   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Test Coverage

Coverage 70.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 71
c 1
b 0
f 0
dl 0
loc 186
ccs 34
cts 48
cp 0.7083
rs 10
wmc 29

8 Methods

Rating   Name   Duplication   Size   Complexity  
A isSuccessful() 0 10 5
A getMerchantData() 0 3 1
A getTransactionReference() 0 3 1
C __construct() 0 72 14
A getMessage() 0 9 2
A getCode() 0 9 2
A getKey() 0 7 3
A getCardCountry() 0 3 1
1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use AvaiBookSports\Component\RedsysMessages\Exception\CatalogNotFoundException;
6
use AvaiBookSports\Component\RedsysMessages\Factory;
7
use AvaiBookSports\Component\RedsysMessages\Loader\CatalogLoader;
8
use Http\Discovery\MessageFactoryDiscovery;
9
use Omnipay\Common\Exception\InvalidResponseException;
10
use Omnipay\Common\Http\Exception\RequestException;
11
use Omnipay\Common\Message\AbstractResponse;
12
use Omnipay\Common\Message\RequestInterface;
13
14
/**
15
 * Redsys Purchase Response.
16
 */
17
class RefundResponse extends AbstractResponse
18
{
19
    /** @var string */
20
    protected $returnSignature;
21
22
    /** @var bool */
23
    protected $usingUpcaseResponse = false;
24
25
    /** @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...
26
    protected $redsysMessages;
27
28
    /**
29
     * Constructor.
30
     *
31
     * @param RequestInterface $request the initiating request
32
     * @param mixed            $data
33
     *
34 2
     * @throws InvalidResponseException If resopnse format is incorrect, data is missing, or signature does not match
35
     */
36 2
    public function __construct(RequestInterface $request, $data)
37
    {
38
        parent::__construct($request, $data);
39 2
40 2
        $security = new Security();
41
42
        try {
43
            $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...
44 2
        } catch (CatalogNotFoundException $e) {
45
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
46 2
        }
47
48
        if (!isset($data['CODIGO'])) {
49
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
50 2
        }
51 1
52
        if (!isset($data['OPERACION'])) {
53
            if ('0' == $data['CODIGO']) {
54 1
                throw new InvalidResponseException('Invalid response from payment gateway (no data)');
55 1
            }
56
        }
57
58
        // Exceeder API rate limit
59
        if ('SIS0295' == $data['CODIGO'] || '9295' == $data['CODIGO']) {
60
            throw new RequestException('Too many requests. "'.$data['CODIGO'].'"', MessageFactoryDiscovery::find()->createRequest('POST', $this->getRequest()->getEndpoint(), ['SOAPAction' => 'trataPeticion'] /* $requestEnvelope */));
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

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

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