Test Setup Failed
Push — main ( 4d31c9...40fd38 )
by امید
03:06
created

ParsianRefund::getToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
namespace HopeOfIran\ParsianRefund;
4
5
use HopeOfIran\ParsianRefund\Utils\RSAProcessor;
6
use Illuminate\Support\Facades\Http;
7
8
class ParsianRefund
9
{
10
    /**
11
     *  Refund card deposit number, if not filled, will be taken from the original transaction.
12
     *
13
     * @var string
14
     */
15
    protected $targetCardNumber;
16
    /**
17
     * Unique code that is generated by the user of the system and increases numerically by one step (1 to 900000000000000000000)
18
     *
19
     * @var int
20
     */
21
    protected $refundId;
22
    /**
23
     * Bank reference number with which the transaction was successful
24
     *
25
     * @var int
26
     */
27
    protected $rrn;
28
    /**
29
     * refund amount
30
     *
31
     * @var int
32
     */
33
    protected $amount = 0;
34
    /**
35
     * Refund settings
36
     *
37
     * @var array
38
     */
39
    protected $settings = [];
40
    /**
41
     * @var \phpseclib3\Crypt\RSA
42
     */
43
    private $CRYPT_RSA;
44
    /**
45
     * @var string
46
     */
47
    protected $token = '';
48
49
    /**
50
     * @param $settings
51
     *
52
     * @throws \Exception
53
     */
54
    public function __construct($settings)
55
    {
56
        $this->settings  = empty($settings) ? $this->loadDefaultConfig() : $settings;
57
        $this->CRYPT_RSA = new RSAProcessor($this->settings['certificate'], $this->settings['certificateType']);
0 ignored issues
show
Documentation Bug introduced by
It seems like new HopeOfIran\ParsianRe...ngs['certificateType']) of type HopeOfIran\ParsianRefund\Utils\RSAProcessor is incompatible with the declared type phpseclib3\Crypt\RSA of property $CRYPT_RSA.

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...
58
    }
59
60
    /**
61
     * Retrieve default config.
62
     *
63
     * @return array
64
     */
65
    protected function loadDefaultConfig() : array
66
    {
67
        return require(static::getDefaultConfigPath());
68
    }
69
70
    /**
71
     * Retrieve Default config's path.
72
     *
73
     * @return string
74
     */
75
    public static function getDefaultConfigPath() : string
76
    {
77
        return __DIR__.'/config/parsianRefund.php';
78
    }
79
80
    /**
81
     * @param  string  $targetCardNumber
82
     *
83
     * @return $this
84
     */
85
    public function targetCardNumber(string $targetCardNumber)
86
    {
87
        $this->targetCardNumber = $targetCardNumber;
88
        return $this;
89
    }
90
91
    /**
92
     * @param  int  $amount
93
     *
94
     * @return $this
95
     */
96
    public function amount(int $amount)
97
    {
98
        $this->amount = $amount;
99
        return $this;
100
    }
101
102
    /**
103
     * @param  int  $refundId
104
     *
105
     * @return $this
106
     */
107
    public function refundId(int $refundId)
108
    {
109
        $this->refundId = $refundId;
110
        return $this;
111
    }
112
113
    /**
114
     * @param  int  $rrn
115
     *
116
     * @return $this
117
     */
118
    public function RRN(int $rrn)
119
    {
120
        $this->rrn = $rrn;
121
        return $this;
122
    }
123
124
    /**
125
     * Set custom configs
126
     * we can use this method when we want to use dynamic configs
127
     *
128
     * @param $key
129
     * @param $value  |null
0 ignored issues
show
Documentation Bug introduced by
The doc comment |null at position 0 could not be parsed: Unknown type name '|' at position 0 in |null.
Loading history...
130
     *
131
     * @return $this
132
     */
133
    public function config($key, $value = null)
134
    {
135
        $configs = [];
136
        $key     = is_array($key) ? $key : [$key => $value];
137
        foreach ($key as $k => $v) {
138
            $configs[$k] = $v;
139
        }
140
        $this->settings = array_merge((array) $this->settings, $configs);
141
        return $this;
142
    }
143
144
    /**
145
     * @return \Illuminate\Http\Client\PendingRequest
146
     */
147
    protected function httpRequest() : \Illuminate\Http\Client\PendingRequest
148
    {
149
        $response = Http::baseUrl($this->settings['apiRefundUrl'])
150
            ->withBasicAuth($this->settings['username'], $this->settings['password'])
151
            ->asForm();
152
        if ($this->settings['withoutVerifying'] === 'true') {
153
            $response->withoutVerifying();
154
        }
155
        return $response;
156
    }
157
158
    /**
159
     * @param  array  $data
160
     *
161
     * @return array
162
     */
163
    protected function getRequest(array $data)
164
    {
165
        $plaintext   = json_encode($data);
166
        $request     = base64_encode($this->CRYPT_RSA->encrypt($plaintext));
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on phpseclib3\Crypt\RSA. It seems like you code against a sub-type of phpseclib3\Crypt\RSA such as phpseclib3\Crypt\RSA\PublicKey. ( Ignorable by Annotation )

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

166
        $request     = base64_encode($this->CRYPT_RSA->/** @scrutinizer ignore-call */ encrypt($plaintext));
Loading history...
167
        $requestSign = base64_encode($this->CRYPT_RSA->sign($request));
0 ignored issues
show
Bug introduced by
The method sign() does not exist on phpseclib3\Crypt\RSA. It seems like you code against a sub-type of phpseclib3\Crypt\RSA such as phpseclib3\Crypt\RSA\PrivateKey. ( Ignorable by Annotation )

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

167
        $requestSign = base64_encode($this->CRYPT_RSA->/** @scrutinizer ignore-call */ sign($request));
Loading history...
168
        return [
169
            "Request"     => $request,
170
            "RequestSign" => $requestSign,
171
        ];
172
    }
173
174
    /**
175
     * @param  callable  $finalizeCallback
176
     *
177
     * @return string
178
     * @throws \Exception
179
     */
180
    public function refund(callable $finalizeCallback = null)
181
    {
182
        $response = $this->doRefund();
183
        if ($finalizeCallback) {
184
            return call_user_func($finalizeCallback, $this, $response->json());
185
        }
186
        return $response;
187
    }
188
189
    /**
190
     * @param  string  $token
191
     *
192
     * @return \Illuminate\Http\Client\Response
193
     * @throws \Exception
194
     */
195
    public function approve(string $token = null)
196
    {
197
        if ($token == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $token of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
198
            $token = $this->doRefund();
199
        }
200
        return $this->httpRequest()->post("approve", $this->getRequest(["Token" => $token]));
201
    }
202
203
    /**
204
     * @param  string  $token
205
     *
206
     * @return \Illuminate\Http\Client\Response
207
     * @throws \Exception
208
     */
209
    public function cancel(string $token = null)
210
    {
211
        if ($token == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $token of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
212
            $token = $this->doRefund();
213
        }
214
        return $this->httpRequest()->post("cancel", $this->getRequest(["Token" => $token]));
215
    }
216
217
    /**
218
     * @param  string  $token
219
     *
220
     * @return \Illuminate\Http\Client\Response
221
     * @throws \Exception
222
     */
223
    public function inquiry(string $token = null)
224
    {
225
        if ($token == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $token of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
226
            $token = $this->doRefund();
227
        }
228
        return $this->httpRequest()->post("Inquiry", $this->getRequest(["Token" => $token]));
229
    }
230
231
    public function getToken()
232
    {
233
        if ($this->token == null) {
234
            $this->doRefund();
235
        }
236
        return $this->token;
237
    }
238
239
    /**
240
     * @return \Illuminate\Http\Client\Response
241
     * @throws \Exception
242
     */
243
    private function doRefund() : \Illuminate\Http\Client\Response
244
    {
245
        if ($this->rrn == null) {
246
            throw new \Exception('RRN is requrred');
247
        }
248
        if ($this->refundId == null) {
249
            throw new \Exception('RefundID is requrred');
250
        }
251
        $fields = [
252
            "RefundId" => $this->refundId,
253
            "RRN"      => $this->rrn,
254
            "Amount"   => $this->amount,
255
        ];
256
        if ($this->targetCardNumber) {
257
            $fields['TargetCardNumber'] = $this->targetCardNumber;
258
        }
259
        $response = $this->httpRequest()->post("doRefund", $this->getRequest($fields));
260
        if ($response->json('Data') == null) {
261
            throw new \Exception($response->json('Message'), $response->json('Status'));
262
        }
263
        $this->token = $response->json('Data')['Token'];
264
265
        return $response;
266
    }
267
}