CompletePurchaseResponse::getKey()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 3
rs 10
1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use AvaiBookSports\Component\RedsysMessages\CatalogInterface;
6
use AvaiBookSports\Component\RedsysMessages\Exception\CatalogNotFoundException;
7
use AvaiBookSports\Component\RedsysMessages\Factory;
8
use AvaiBookSports\Component\RedsysMessages\Loader\CatalogLoader;
9
use Omnipay\Common\Exception\InvalidResponseException;
10
use Omnipay\Common\Message\RequestInterface;
11
12
/**
13
 * Redsys Complete Purchase Response.
14
 */
15
class CompletePurchaseResponse extends AbstractResponse
16
{
17
    /** @var array */
18
    protected $merchantParameters;
19
20
    /** @var string */
21
    protected $returnSignature;
22
23
    /** @var bool */
24
    protected $usingUpcaseParameters = false;
25
26
    /** @var bool */
27
    protected $usingUpcaseResponse = false;
28
29
    /** @var CatalogInterface */
30
    protected $redsysMessages;
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param RequestInterface $request the initiating request
36
     * @param mixed            $data
37
     *
38
     * @throws InvalidResponseException If merchant data or order number is missing, or signature does not match
39
     */
40
    public function __construct(RequestInterface $request, $data)
41 10
    {
42
        parent::__construct($request, $data);
43 10
44
        $security = new Security();
45 10
46
        try {
47
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage(array_key_exists('language', $this->request->getParameters()) ? $this->request->getParameters()['language'] : 'en');
48 10
        } catch (CatalogNotFoundException $e) {
49 10
            $this->redsysMessages = (new Factory(new CatalogLoader()))->createCatalogByLanguage('en');
50
        }
51
52
        if (!empty($data['Ds_MerchantParameters'])) {
53 10
            $this->merchantParameters = $security->decodeMerchantParameters($data['Ds_MerchantParameters']);
54 8
        } elseif (!empty($data['DS_MERCHANTPARAMETERS'])) {
55 10
            $this->merchantParameters = $security->decodeMerchantParameters($data['DS_MERCHANTPARAMETERS']);
56 1
            $this->usingUpcaseResponse = true;
57 1
        } else {
58 1
            throw new InvalidResponseException('Invalid response from payment gateway (no data)');
59 1
        }
60
61
        if (!empty($this->merchantParameters['Ds_Order'])) {
62 9
            $order = $this->merchantParameters['Ds_Order'];
63 7
        } elseif (!empty($this->merchantParameters['DS_ORDER'])) {
64 9
            $order = $this->merchantParameters['DS_ORDER'];
65 1
            $this->usingUpcaseParameters = true;
66 1
        } else {
67 1
            throw new InvalidResponseException();
68 1
        }
69
70
        $this->returnSignature = $security->createReturnSignature(
71 8
            $data[$this->usingUpcaseResponse ? 'DS_MERCHANTPARAMETERS' : 'Ds_MerchantParameters'],
72 8
            $order,
73 8
            $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

73
            $this->request->/** @scrutinizer ignore-call */ 
74
                            getHmacKey()
Loading history...
74 8
        );
75 8
76
        if ($this->returnSignature != $data[$this->usingUpcaseResponse ? 'DS_SIGNATURE' : 'Ds_Signature']) {
77 8
            throw new InvalidResponseException('Invalid response from payment gateway (signature mismatch)');
78 1
        }
79
    }
80 7
81
    /**
82
     * Is the response successful?
83
     *
84
     * @return bool
85
     */
86
    public function isSuccessful()
87 7
    {
88
        $key = $this->usingUpcaseParameters ? 'DS_RESPONSE' : 'Ds_Response';
89 7
90
        return isset($this->merchantParameters[$key])
91 7
            && is_numeric($this->merchantParameters[$key])
92 7
            && 0 <= $this->merchantParameters[$key]
93 7
            && 100 > $this->merchantParameters[$key];
94 7
    }
95
96
    /**
97
     * Is the transaction cancelled by the user?
98
     *
99
     * @return bool
100
     */
101
    public function isCancelled()
102
    {
103
        return '9915' === $this->getCode();
104
    }
105
106
    /**
107
     * Get the response data, included the decoded merchant parameters if available.
108
     *
109
     * @return mixed
110
     */
111
    public function getData()
112 4
    {
113
        $data = parent::getData();
114 4
115
        return is_array($data) && is_array($this->merchantParameters)
116 4
            ? array_merge($data, $this->merchantParameters)
117 4
            : $data;
118 4
    }
119
120
    /**
121
     * Helper method to get a specific merchant parameter if available.
122
     *
123
     * @param string $key The key to look up
124
     *
125
     * @return mixed|null
126
     */
127
    protected function getKey($key)
128 7
    {
129
        if ($this->usingUpcaseParameters) {
130 7
            $key = strtoupper($key);
131 1
        }
132 1
133
        return isset($this->merchantParameters[$key]) ? $this->merchantParameters[$key] : null;
134 7
    }
135
136
    /**
137
     * Get the authorisation code if available.
138
     *
139
     * @return string|null
140
     */
141
    public function getTransactionReference()
142 3
    {
143
        return $this->getAuthorisationCode();
144 3
    }
145
146
    /**
147
     * Get the merchant message if available.
148
     *
149
     * @return string|null A response message from the payment gateway
150
     */
151
    public function getMessage()
152
    {
153
        return $this->redsysMessages->getDsResponseMessage($this->getCode());
154
    }
155
156
    /**
157
     * Get the merchant response code if available.
158
     *
159
     * @return string|null
160
     */
161
    public function getCode()
162 7
    {
163
        return $this->getKey('Ds_Response');
164 7
    }
165
166
    /**
167
     * Get the card type if available.
168
     *
169
     * @return string|null
170
     */
171
    public function getCardType()
172 2
    {
173
        return $this->getKey('Ds_Card_Type');
174 2
    }
175
}
176