Test Setup Failed
Push — main ( ba22bd...414025 )
by امید
11:53 queued 38s
created

ParsianRefund::RRN()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
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->refundId  = time();
58
        $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...
59
    }
60
61
    /**
62
     * Retrieve default config.
63
     *
64
     * @return array
65
     */
66
    protected function loadDefaultConfig() : array
67
    {
68
        return require(static::getDefaultConfigPath());
69
    }
70
71
    /**
72
     * Retrieve Default config's path.
73
     *
74
     * @return string
75
     */
76
    public static function getDefaultConfigPath() : string
77
    {
78
        return __DIR__.'/config/parsianRefund.php';
79
    }
80
81
    /**
82
     * @param  string  $targetCardNumber
83
     *
84
     * @return $this
85
     */
86
    public function targetCardNumber(string $targetCardNumber)
87
    {
88
        $this->targetCardNumber = $targetCardNumber;
89
        return $this;
90
    }
91
92
    /**
93
     * @param  int  $amount
94
     *
95
     * @return $this
96
     */
97
    public function amount(int $amount)
98
    {
99
        $this->amount = $amount;
100
        return $this;
101
    }
102
103
    /**
104
     * @param  int  $refundId
105
     *
106
     * @return $this
107
     */
108
    public function refundId(int $refundId)
109
    {
110
        $this->refundId = $refundId;
111
        return $this;
112
    }
113
114
    /**
115
     * @param  int  $rrn
116
     *
117
     * @return $this
118
     */
119
    public function RRN(int $rrn)
120
    {
121
        $this->rrn = $rrn;
122
        return $this;
123
    }
124
125
    /**
126
     * Set custom configs
127
     * we can use this method when we want to use dynamic configs
128
     *
129
     * @param $key
130
     * @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...
131
     *
132
     * @return $this
133
     */
134
    public function config($key, $value = null)
135
    {
136
        $configs = [];
137
        $key     = is_array($key) ? $key : [$key => $value];
138
        foreach ($key as $k => $v) {
139
            $configs[$k] = $v;
140
        }
141
        $this->settings = array_merge((array) $this->settings, $configs);
142
        return $this;
143
    }
144
145
    /**
146
     * @return \Illuminate\Http\Client\PendingRequest
147
     */
148
    protected function httpRequest() : \Illuminate\Http\Client\PendingRequest
149
    {
150
        $response = Http::baseUrl($this->settings['apiRefundUrl'])
151
            ->withBasicAuth($this->settings['username'], $this->settings['password'])
152
            ->asForm();
153
        if ($this->settings['withoutVerifying'] === 'true') {
154
            $response->withoutVerifying();
155
        }
156
        return $response;
157
    }
158
159
    /**
160
     * @param  array  $data
161
     *
162
     * @return array
163
     */
164
    protected function getRequest(array $data)
165
    {
166
        $plaintext   = json_encode($data);
167
        $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

167
        $request     = base64_encode($this->CRYPT_RSA->/** @scrutinizer ignore-call */ encrypt($plaintext));
Loading history...
168
        $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

168
        $requestSign = base64_encode($this->CRYPT_RSA->/** @scrutinizer ignore-call */ sign($request));
Loading history...
169
        return [
170
            "Request"     => $request,
171
            "RequestSign" => $requestSign,
172
        ];
173
    }
174
175
    /**
176
     * @param  callable  $finalizeCallback
177
     *
178
     * @return string
179
     * @throws \Exception
180
     */
181
    public function refund(callable $finalizeCallback = null)
182
    {
183
        $response = $this->doRefund();
184
        if ($finalizeCallback) {
185
            return call_user_func($finalizeCallback, $this, $response->json());
186
        }
187
        return $response;
188
    }
189
190
    /**
191
     * @param  string  $token
192
     *
193
     * @return \Illuminate\Http\Client\Response
194
     * @throws \Exception
195
     */
196
    public function approve(string $token = null)
197
    {
198
        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...
199
            $token = $this->getToken();
200
        }
201
        return $this->httpRequest()->post("approve", $this->getRequest(["Token" => $token]));
202
    }
203
204
    /**
205
     * @param  string  $token
206
     *
207
     * @return \Illuminate\Http\Client\Response
208
     * @throws \Exception
209
     */
210
    public function cancel(string $token = null)
211
    {
212
        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...
213
            $token = $this->getToken();
214
        }
215
        return $this->httpRequest()->post("cancel", $this->getRequest(["Token" => $token]));
216
    }
217
218
    /**
219
     * @param  string  $token
220
     *
221
     * @return \Illuminate\Http\Client\Response
222
     * @throws \Exception
223
     */
224
    public function inquiry(string $token = null)
225
    {
226
        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...
227
            $token = $this->getToken();
228
        }
229
        return $this->httpRequest()->post("Inquiry", $this->getRequest(["Token" => $token]));
230
    }
231
232
    /**
233
     * @return string
234
     * @throws \Exception
235
     */
236
    public function getToken()
237
    {
238
        if ($this->token == null) {
239
            $this->doRefund();
240
        }
241
        return $this->token;
242
    }
243
244
    /**
245
     * @return \Illuminate\Http\Client\Response
246
     * @throws \Exception
247
     */
248
    private function doRefund() : \Illuminate\Http\Client\Response
249
    {
250
        $fields   = $this->getFields();
251
        $response = $this->httpRequest()->post("doRefund", $this->getRequest($fields));
252
        if ($response->json('Data') == null) {
253
            throw new \Exception($response->json('Message'), $response->json('Status'));
254
        }
255
        $this->token = $response->json('Data')['Token'];
256
257
        return $response;
258
    }
259
260
    /**
261
     * @return array
262
     * @throws \Exception
263
     */
264
    private function getFields() : array
265
    {
266
        if ($this->rrn == null) {
267
            throw new \Exception('RRN is requrred');
268
        }
269
        $fields = [
270
            "RefundId" => $this->refundId,
271
            "RRN"      => $this->rrn,
272
        ];
273
        if ($this->amount) {
274
            $fields['Amount'] = $this->amount;
275
        }
276
        if ($this->targetCardNumber) {
277
            $fields['TargetCardNumber'] = $this->targetCardNumber;
278
        }
279
        return $fields;
280
    }
281
282
    /**
283
     * @return int
284
     */
285
    public function getRefundId() : int
286
    {
287
        return $this->refundId;
288
    }
289
}