Passed
Push — master ( a81e51...a9e404 )
by Alex
04:19
created

Gateway::interactStateless()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 22
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace Nxmad\Larapay\Abstracts;
4
5
use RuntimeException;
6
use Illuminate\Config\Repository;
7
use Nxmad\Larapay\Models\Transaction;
8
use Nxmad\Larapay\Contracts\Gateway as GatewayContract;
9
10
abstract class Gateway implements GatewayContract
11
{
12
    /**
13
     * The list of aliases for payment gateway.
14
     *
15
     * @var array
16
     */
17
    protected $aliases = [];
18
19
    /**
20
     * The list of required request attributes.
21
     *
22
     * @var array
23
     */
24
    protected $required = [];
25
26
    /**
27
     * The general settings for payment processor, like secret key or merchant id.
28
     *
29
     * @var Repository
30
     */
31
    protected $config;
32
33
    /**
34
     * The temporary settings for payment processor, actual only in for this request, like payment description, etc.
35
     *
36
     * @var Repository
37
     */
38
    protected $custom;
39
40
    /**
41
     * Default gateway slug.
42
     * You should override this property.
43
     *
44
     * @var string|bool
45
     */
46
    static $slug = false;
47
48
    /**
49
     * Payment process method.
50
     * Possible values are below.
51
     *
52
     * @var string
53
     */
54
    protected $method = self::LARAPAY_GET_REDIRECT;
55
56
    /**
57
     * Classic redirection with GET parameters.
58
     */
59
    const LARAPAY_GET_REDIRECT = 'GET';
60
61
    /**
62
     * Redirect with POST data for old gateways (using hack with form).
63
     */
64
    const LARAPAY_POST_REDIRECT = 'POST';
65
66
    /**
67
     * No redirect method (e.g. for card payments)
68
     */
69
    const LARAPAY_NO_REDIRECT = '_';
70
71
    /**
72
     * Sign outcome request (insert request signature in request parameters).
73
     *
74
     * @param array $data
75
     *
76
     * @return string
77
     */
78
    abstract public function sign(array $data): string;
79
80
    /**
81
     * Gateway constructor.
82
     *
83
     * @param array $config
84
     */
85
    public function __construct(array $config = [])
86
    {
87
        $this->custom = new Repository;
88
        $this->config = new Repository($config);
89
    }
90
91
    /**
92
     * Process payment.
93
     *
94
     * @param Transaction $transaction
95
     * @param bool $stateless
96
     *
97
     * @return mixed
98
     */
99
    public function interact(Transaction $transaction, $stateless = false)
100
    {
101
        $this->prepare($transaction);
102
        $this->fill([
103
            'amount'      => $transaction->getAmount(),
104
            'description' => $transaction->getDescription(),
105
            'id'          => $transaction->getPrimaryValue(),
106
        ]);
107
108
        $this->signature = $this->sign($this->custom->all());
0 ignored issues
show
Bug Best Practice introduced by
The property signature does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
109
110
        foreach ($this->required as $field) {
111
            if (! $this->custom->has($this->getAlias($field))) {
112
                throw new RuntimeException("Required field [{$field}] is not presented.");
113
            }
114
        }
115
116
        if ($stateless) {
117
            return $this->interactStateless($transaction);
118
        }
119
120
        if ($this->method == self::LARAPAY_NO_REDIRECT) {
121
            return $this->customBehavior($transaction);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->customBehavior($transaction) targeting Nxmad\Larapay\Abstracts\Gateway::customBehavior() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
122
        }
123
124
        if ($this->method == self::LARAPAY_GET_REDIRECT) {
125
            return redirect()->away($this->getInteractionUrl() . '?' . http_build_query($this->custom->all()));
126
        }
127
128
        return view('larapay::form', [
129
            'method' => 'POST',
130
            'data'   => $this->custom->all(),
131
            'action' => $this->getInteractionUrl(),
132
        ]);
133
    }
134
135
    /**
136
     * Stateless interaction.
137
     *
138
     * @param Transaction $transaction
139
     *
140
     * @return array
141
     */
142
    public function interactStateless(Transaction $transaction)
143
    {
144
        if ($this->method == self::LARAPAY_NO_REDIRECT)
145
        {
146
            return [
147
                'type' => 'custom',
148
                'data' => $this->customBehavior($transaction),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->customBehavior($transaction) targeting Nxmad\Larapay\Abstracts\Gateway::customBehavior() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
149
            ];
150
        }
151
152
        $response = [
153
            'type' => 'redirect',
154
            'method' => $this->method,
155
            'data' => $this->custom->all(),
156
            'url' => $this->getInteractionUrl(),
157
        ];
158
159
        if ($this->method == self::LARAPAY_GET_REDIRECT) {
160
            $response['url'] .= '?' . http_build_query($response['data']);
161
        }
162
163
        return $response;
164
    }
165
166
    /**
167
     * Custom gateway logic instead redirect.
168
     * You can override this method in children class.
169
     *
170
     * @param Transaction $transaction
171
     */
172
    public function customBehavior(Transaction $transaction)
0 ignored issues
show
Unused Code introduced by
The parameter $transaction is not used and could be removed. ( Ignorable by Annotation )

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

172
    public function customBehavior(/** @scrutinizer ignore-unused */ Transaction $transaction)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
173
    {
174
    }
175
176
    /**
177
     * Prepare Transaction.
178
     * You can override this method in children class.
179
     *
180
     * @param Transaction $transaction
181
     */
182
    public function prepare(Transaction $transaction)
0 ignored issues
show
Unused Code introduced by
The parameter $transaction is not used and could be removed. ( Ignorable by Annotation )

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

182
    public function prepare(/** @scrutinizer ignore-unused */ Transaction $transaction)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
183
    {
184
    }
185
186
    /**
187
     * Determine if this gateway needs redirect.
188
     *
189
     * @return bool
190
     */
191
    public function needRedirect()
192
    {
193
        return $this->method != self::LARAPAY_NO_REDIRECT;
194
    }
195
196
    /**
197
     * Fill custom parameters.
198
     *
199
     * @param array $parameters
200
     *
201
     * @return Gateway
202
     */
203
    public function fill(array $parameters): self
204
    {
205
        foreach ($parameters as $key => $value) {
206
            $this->set($key, $value);
207
        }
208
209
        return $this;
210
    }
211
212
    /**
213
     * Set custom field value respecting aliases.
214
     *
215
     * @param $field
216
     * @param $value
217
     *
218
     * @return self
219
     */
220
    public function set($field, $value = null): self
221
    {
222
        if (is_array($field)) {
223
            return $this->fill($field);
224
        }
225
226
        $this->custom->set($this->getAlias($field), $value);
227
228
        return $this;
229
    }
230
231
    /**
232
     * Magic set method.
233
     *
234
     * @param $name
235
     * @param $value
236
     *
237
     * @return Gateway
238
     */
239
    public function __set($name, $value)
240
    {
241
        return self::set(...func_get_args());
0 ignored issues
show
Bug introduced by
func_get_args() is expanded, but the parameter $field of Nxmad\Larapay\Abstracts\Gateway::set() does not expect variable arguments. ( Ignorable by Annotation )

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

241
        return self::set(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
Bug Best Practice introduced by
The method Nxmad\Larapay\Abstracts\Gateway::set() is not static, but was called statically. ( Ignorable by Annotation )

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

241
        return self::/** @scrutinizer ignore-call */ set(...func_get_args());
Loading history...
242
    }
243
244
    /**
245
     * Get custom field value respecting aliases.
246
     *
247
     * @param string  $field
248
     * @param mixed   $default
249
     *
250
     * @return mixed
251
     */
252
    public function get(string $field, $default = null)
253
    {
254
        return $this->custom->get($this->getAlias($field), $default);
255
    }
256
257
    /**
258
     * Magic get method.
259
     *
260
     * @param $name
261
     *
262
     * @return mixed
263
     */
264
    public function __get($name)
265
    {
266
        return self::get(...func_get_args());
0 ignored issues
show
Bug Best Practice introduced by
The method Nxmad\Larapay\Abstracts\Gateway::get() is not static, but was called statically. ( Ignorable by Annotation )

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

266
        return self::/** @scrutinizer ignore-call */ get(...func_get_args());
Loading history...
Bug introduced by
func_get_args() is expanded, but the parameter $field of Nxmad\Larapay\Abstracts\Gateway::get() does not expect variable arguments. ( Ignorable by Annotation )

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

266
        return self::get(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
267
    }
268
269
    /**
270
     * Get slug of gateway based on class name.
271
     *
272
     * @return string
273
     */
274
    static public function getSlug(): string
275
    {
276
        return self::$slug ?: str_slug(array_last(explode('\\', get_called_class())));
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::slug ?: str..., get_called_class()))) could return the type true which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
277
    }
278
279
    /**
280
     * Determine if field has alias for payment gateway.
281
     * E.g., some gateways can accept description in $_GET parameter vendorPrefix_desc,
282
     * so we need conversion: 'description' => 'vendorPrefix_desc'.
283
     *
284
     * @param string $field
285
     *
286
     * @return string
287
     */
288
    protected function getAlias(string $field): string
289
    {
290
        if (isset($this->aliases[$field])) {
291
            return $this->aliases[$field];
292
        }
293
294
        return $field;
295
    }
296
}
297