Passed
Push — master ( 437f23...0ad4c0 )
by mahdi
03:18
created

Asanpardakht::verify()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 63
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
c 1
b 0
f 0
dl 0
loc 63
rs 8.5066
cc 7
nc 6
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Shetabit\Payment\Drivers\Asanpardakht;
4
5
use Shetabit\Payment\Abstracts\Driver;
6
use Shetabit\Payment\Exceptions\{InvalidPaymentException, PurchaseFailedException};
7
use Shetabit\Payment\{Contracts\ReceiptInterface, Invoice, Receipt};
8
9
class Asanpardakht extends Driver
10
{
11
    /**
12
     * Invoice
13
     *
14
     * @var Invoice
15
     */
16
    protected $invoice;
17
18
    /**
19
     * Driver settings
20
     *
21
     * @var object
22
     */
23
    protected $settings;
24
25
    /**
26
     * Asanpardakht constructor.
27
     * Construct the class with the relevant settings.
28
     *
29
     * @param Invoice $invoice
30
     * @param $settings
31
     */
32
    public function __construct(Invoice $invoice, $settings)
33
    {
34
        $this->invoice($invoice);
35
        $this->settings = (object)$settings;
36
    }
37
38
    /**
39
     * Purchase Invoice.
40
     *
41
     * @return string
42
     *
43
     * @throws PurchaseFailedException
44
     * @throws \SoapFault
45
     */
46
    public function purchase()
47
    {
48
        $opts = array(
49
            'ssl' => array(
50
                'verify_peer' => false,
51
                'verify_peer_name' => false
52
            )
53
        );
54
        $configs = array ('stream_context' => stream_context_create($opts));
55
56
        $client = new \SoapClient($this->settings->apiPurchaseUrl, $configs);
57
58
        $params = $this->preparePurchaseData();
59
        $result = $client->RequestOperation($params);
60
61
        if (! $result) {
62
            throw  new PurchaseFailedException('خطای فراخوانی متد درخواست تراکنش.');
63
        }
64
65
        $result = $result->RequestOperationResult;
66
67
        if ($result{0} != '0') {
68
            $message = "خطای شماره ".$result." رخ داده است.";
69
            throw  new PurchaseFailedException($message);
70
        }
71
72
        $this->invoice->transactionId(substr($result,2));
73
74
        // return the transaction's id
75
        return $this->invoice->getTransactionId();
76
    }
77
78
    /**
79
     * Pay the Invoice
80
     *
81
     * @return \Illuminate\Http\RedirectResponse|mixed
82
     */
83
    public function pay()
84
    {
85
        $payUrl = $this->settings->apiPaymentUrl;
86
87
        return $this->redirectWithForm(
88
            $payUrl,
89
            ['RefId' => $this->invoice->getTransactionId()],
90
            'POST'
91
        );
92
    }
93
94
    /**
95
     * Verify payment
96
     *
97
     * @return mixed|Receipt
98
     *
99
     * @throws InvalidPaymentException
100
     * @throws \SoapFault
101
     */
102
    public function verify() : ReceiptInterface
103
    {
104
        $encryptedReturningParamsString = request()->get('ReturningParams');
105
        $returningParamsString = decrypt($encryptedReturningParamsString);
106
        $returningParams = explode(",", $returningParamsString);
107
108
        /**
109
         * other data:
110
         *   $amount = $returningParams[0];
111
         *   $saleOrderId = $returningParams[1];
112
         *   $refId = $this->invoice->getTransactionId() ?? $returningParams[2];
113
         *   $resMessage = $returningParams[4];
114
         *   $rrn = $returningParams[6];
115
         *   $lastFourDigitOfPAN = $returningParams[7];
116
        **/
117
118
        $resCode = $returningParams[3];
119
        $payGateTranID = $returningParams[5];
120
121
        if ($resCode != '0' && $resCode != '00') {
122
            $message =  "خطای شماره " . $resCode . " رخ داده و تراکنش ناموفق بوده است.";
123
            throw new InvalidPaymentException($message);
124
        }
125
126
        $opts = array(
127
            'ssl' => array(
128
                'verify_peer' => false,
129
                'verify_peer_name' => false
130
            )
131
        );
132
        $configs = array ('stream_context' => stream_context_create($opts));
133
134
        $client = new \SoapClient($this->settings->apiVerificationUrl, $configs);
135
136
        $params = $this->prepareVerificationData($payGateTranID);
137
138
        // step1: verify
139
        $result = $client->RequestVerification($params);
140
141
        if (! $result) {
142
            throw new InvalidPaymentException("خطای فراخوانی متد وريفای رخ داده است.");
143
        }
144
145
        $result = $result->RequestVerificationResult;
146
        if ($result != '500') {
147
            $message = "خطای شماره: ".$result." در هنگام Verify";
148
            throw  new InvalidPaymentException($message);
149
        }
150
151
        // step2: settle
152
        $result = $client->RequestReconciliation($params);
153
154
        if(! $result) {
155
            throw new InvalidPaymentException('خطای فراخوانی متد تسويه رخ داده است.');
156
        }
157
158
        $result = $result->RequestReconciliationResult;
159
        if ($result != '600') {
160
            $message = "خطای شماره: ".$result." در هنگام Settlement";
161
            throw new InvalidPaymentException($message);
162
        }
163
164
        return $this->createReceipt($payGateTranID);
165
    }
166
167
    /**
168
     * Generate the payment's receipt
169
     *
170
     * @param $referenceId
171
     *
172
     * @return Receipt
173
     */
174
    public function createReceipt($referenceId)
175
    {
176
        $receipt = new Receipt('asanpardakht', $referenceId);
177
178
        return $receipt;
179
    }
180
181
    /**
182
     * Prepare data for payment verification
183
     *
184
     * @param $payGateTranID
185
     *
186
     * @return array
187
     *
188
     * @throws \SoapFault
189
     */
190
    public function prepareVerificationData($payGateTranID)
191
    {
192
        $credentials = array(
193
            $this->settings->username,
194
            $this->settings->password
195
        );
196
197
        $encryptedCredentials = $this->encrypt(implode(',', $credentials));
198
199
        return array(
200
            'merchantConfigurationID' => $this->settings->merchantId,
201
            'encryptedCredentials' => $encryptedCredentials,
202
            'payGateTranID' => $payGateTranID
203
        );
204
    }
205
206
    /**
207
     * Prepare data for purchasing invoice
208
     *
209
     * @return array
210
     *
211
     * @throws \SoapFault
212
     */
213
    protected function preparePurchaseData()
214
    {
215
        if (!empty($this->invoice->getDetails()['description'])) {
216
            $description = $this->invoice->getDetails()['description'];
217
        } else {
218
            $description = $this->settings->description;
219
        }
220
221
        // configs
222
        $username = $this->settings->username;
223
        $password = $this->settings->password;
224
        $callBackUrl = $this->settings->callbackUrl;
225
226
        // invoice details
227
        $price = $this->invoice->getAmount() * 10; // convert to rial
228
        $additionalData = $description ?? '';
229
        $orderId = crc32($this->invoice->getUuid());
230
        $localDate = date("Ymd His");
231
232
        // box and encrypt everything
233
        $requestString = "1,{$username},{$password},{$orderId},{$price},{$localDate},{$additionalData},{$callBackUrl},0";
234
        $encryptedRequestString = $this->encrypt($requestString);
235
236
        return array(
237
            'merchantConfigurationID' => $this->settings->merchantId,
238
            'encryptedRequest' => $encryptedRequestString
239
        );
240
    }
241
242
    /**
243
     * Encrypt given string.
244
     *
245
     * @param $string
246
     *
247
     * @return mixed
248
     *
249
     * @throws \SoapFault
250
     */
251
    protected  function encrypt($string)
252
    {
253
        $opts = array(
254
            'ssl' => array(
255
                'verify_peer' => false,
256
                'verify_peer_name' => false
257
            )
258
        );
259
260
        $configs = array('stream_context' => stream_context_create($opts));
261
262
        $client = new \SoapClient($this->settings->apiUtilsUrl, $configs);
263
264
        $params = array(
265
            'aesKey' => $this->settings->key,
266
            'aesVector' => $this->settings->iv,
267
            'toBeEncrypted' => $string
268
        );
269
270
        $result = $client->EncryptInAES($params);
271
272
        return $result->EncryptInAESResult;
273
    }
274
275
    /**
276
     * Decrypt given string.
277
     *
278
     * @param $string
279
     *
280
     * @return mixed
281
     *
282
     * @throws \SoapFault
283
     */
284
    protected function decrypt($string)
285
    {
286
        $opts = array(
287
            'ssl' => array(
288
                'verify_peer'=>false,
289
                'verify_peer_name'=>false
290
            )
291
        );
292
293
        $configs = array('stream_context' => stream_context_create($opts));
294
295
        $client = new \SoapClient($this->settings->apiUtilsUrl, $configs);
296
297
        $params = array(
298
            'aesKey' => $this->settings->key,
299
            'aesVector' => $this->settings->iv,
300
            'toBeDecrypted' => $string
301
        );
302
303
        $result = $client->DecryptInAES($params);
304
305
        return $result->DecryptInAESResult;
306
    }
307
}
308