getTransactionReference()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
c 2
b 1
f 0
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
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 Omnipay\Common\Exception\InvalidResponseException;
9
use Omnipay\Common\Message\RequestInterface;
10
11
/**
12
 * Redsys Purchase Response.
13
 */
14
class WebservicePurchaseResponse extends AbstractResponse
15
{
16
    /** @var string */
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
    /**
26
     * Constructor.
27
     *
28
     * @param RequestInterface $request the initiating request
29
     * @param mixed            $data
30
     *
31
     * @throws InvalidResponseException If resopnse format is incorrect, data is missing, or signature does not match
32
     */
33
    public function __construct(RequestInterface $request, $data)
34 13
    {
35
        parent::__construct($request, $data);
36 13
37
        try {
38
            $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...
39 13
        } catch (CatalogNotFoundException $e) {
40 13
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
41
        }
42
43
        $security = new Security();
44 13
45
        if (!isset($data['CODIGO'])) {
46 13
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
47 1
        }
48
49
        if (!isset($data['OPERACION'])) {
50 12
            if ('0' == $data['CODIGO']) {
51 3
                throw new InvalidResponseException('Invalid response from payment gateway (no data)');
52 1
            } else {
53
                if (null === $this->getMessage()) {
54 2
                    throw new InvalidResponseException('Invalid response from payment gateway: "'.$this->getCode().'"');
55 2
                } else {
56
                    throw new InvalidResponseException('Invalid response from payment gateway: "'.$this->getCode().': '.$this->getMessage().'"');
57
                }
58
            }
59
        }
60
61
        if (isset($data['OPERACION']['DS_ORDER'])) {
62 9
            $this->usingUpcaseResponse = true;
63 1
        }
64 1
65
        $order = $this->GetKey('Ds_Order');
66 9
        if (null === $order) {
67 9
            throw new InvalidResponseException();
68 1
        }
69
70
        $signature_keys = [
71
            'Ds_Amount',
72 8
            'Ds_Order',
73 8
            'Ds_MerchantCode',
74 8
            'Ds_Currency',
75 8
            'Ds_Response',
76 8
            'Ds_TransactionType',
77 8
            'Ds_SecurePayment',
78 8
        ];
79 8
        $signature_data = '';
80 8
        foreach ($signature_keys as $key) {
81 8
            $value = $this->getKey($key);
82 8
            if (null === $value) {
83 8
                throw new InvalidResponseException('Invalid response from payment gateway (missing data)');
84 1
            }
85
            $signature_data .= $value;
86 8
        }
87 8
88
        $this->returnSignature = $security->createSignature(
89 7
            $signature_data,
90 7
            $order,
91 7
            $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

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