Test Failed
Pull Request — master (#256)
by
unknown
02:38
created

Pasargad   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 266
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 98
c 2
b 0
f 0
dl 0
loc 266
rs 10
wmc 16

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getPreparedInvoiceData() 0 7 2
A request() 0 25 3
A __construct() 0 6 1
A pay() 0 6 1
A verify() 0 41 2
A prepareInvoiceData() 0 25 2
A purchase() 0 20 2
A createReceipt() 0 3 1
A createToken() 0 16 2
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Pasargad;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Shetabit\Multipay\Drivers\Pasargad\PasargadHolder\PasargadHolder;
8
use Shetabit\Multipay\Invoice;
9
use Shetabit\Multipay\Receipt;
10
use Shetabit\Multipay\Abstracts\Driver;
11
use Shetabit\Multipay\Contracts\ReceiptInterface;
12
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
13
use Shetabit\Multipay\RedirectionForm;
14
use DateTimeZone;
15
use DateTime;
16
17
class Pasargad extends Driver
18
{
19
    /**
20
     * Guzzle client
21
     *
22
     * @var object
23
     */
24
    protected $client;
25
26
    /**
27
     * Invoice
28
     *
29
     * @var Invoice
30
     */
31
    protected $invoice;
32
33
    /**
34
     * Driver settings
35
     *
36
     * @var object
37
     */
38
    protected $settings;
39
40
    /**
41
     * Prepared invoice's data
42
     *
43
     * @var array
44
     */
45
    protected $preparedData = array();
46
47
    /**
48
     * Pasardad Holder
49
     * @var string
50
     */
51
    protected $holder;
52
53
    /**
54
     * Pasargad(PEP) constructor.
55
     * Construct the class with the relevant settings.
56
     *
57
     * @param Invoice $invoice
58
     * @param $settings
59
     */
60
    public function __construct(Invoice $invoice, $settings)
61
    {
62
        $this->invoice($invoice);
63
        $this->settings = (object)$settings;
64
        $this->client = new Client();
65
        $this->holder = new PasargadHolder();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Shetabit\Multipay\Dr...Holder\PasargadHolder() of type Shetabit\Multipay\Driver...adHolder\PasargadHolder is incompatible with the declared type string of property $holder.

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...
66
    }
67
68
    /**
69
     * Purchase Invoice.
70
     *
71
     * @return string
72
     * @throws InvalidPaymentException
73
     * @throws GuzzleException
74
     * @throws \Exception
75
     */
76
    public function purchase(): string
77
    {
78
        $invoiceData = $this->getPreparedInvoiceData();
79
80
        $this->invoice->transactionId($invoiceData['invoice']);
81
82
        $response = $this->request(
83
            $this->settings->apiPaymentUrl,
84
            $invoiceData,
85
            'POST',
86
            $this->createToken()
87
        );
88
89
        if ($response['data']['urlId']) {
90
            $this->holder->urlId($response['data']['urlId']);
91
        } else {
92
            throw new InvalidPaymentException("urlId is not set.");
93
        }
94
95
        return $this->invoice->getTransactionId();
96
    }
97
98
    /**
99
     * Pay the Invoice
100
     *
101
     * @return RedirectionForm
102
     */
103
    public function pay(): RedirectionForm
104
    {
105
        $paymentUrl = $this->settings->apiBaseUrl . $this->holder->getUrlId();
106
107
        // redirect using HTML form
108
        return $this->redirectWithForm($paymentUrl, ['Token' => $this->holder->getUrlId()]);
109
    }
110
111
    /**
112
     * Verify payment
113
     *
114
     * @return ReceiptInterface
115
     *
116
     * @throws InvalidPaymentException
117
     * @throws \Exception
118
     * @throws GuzzleException
119
     */
120
    public function verify(): ReceiptInterface
121
    {
122
123
        $transactionId = $this->invoice->getTransactionId();
124
125
        $payment_inquiry = $this->request(
126
            $this->settings->paymentInquiry,
127
            ['invoiceId' => $transactionId],
128
            'POST',
129
            $this->createToken()
130
        );
131
132
        if ($payment_inquiry['resultCode'] != 0) {
133
            throw new InvalidPaymentException("This transaction is fail.");
134
        }
135
136
        $verifyResult = $this->request(
137
            $this->settings->verifyPayment,
138
            [
139
                'invoice' => $transactionId,
140
                'urlId' => $payment_inquiry['url']
141
            ],
142
            'POST',
143
            $this->createToken()
144
        );
145
146
        $receipt =  $this->createReceipt($transactionId);
147
148
        $receipt->detail([
149
            'resultCode' => $verifyResult['resultCode'],
150
            'resultMsg' => $verifyResult['resultMsg'] ?? null,
151
            'hashedCardNumber' => $verifyResult['data']['hashedCardNumber'] ?? null,
152
            'maskedCardNumber' => $verifyResult['data']['maskedCardNumber'] ?? null,
153
            'invoiceId' => $transactionId,
154
            'referenceNumber' =>  $verifyResult['data']['maskedCardNumber'] ?? null,
155
            'trackId' =>  $verifyResult['data']['trackId'] ?? null,
156
            'amount' =>  $verifyResult['data']['amount'] ?? null,
157
            'requestDate' => $verifyResult['data']['requestDate'] ?? null,
158
        ]);
159
160
        return $receipt;
161
    }
162
163
164
    /**
165
     * Generate the payment's receipt
166
     *
167
     * @param $referenceId
168
     * @return Receipt
169
     */
170
    protected function createReceipt($referenceId): Receipt
171
    {
172
        return new Receipt('pasargad', $referenceId);
173
    }
174
175
    /**
176
     * Retrieve prepared invoice's data
177
     *
178
     * @return array
179
     * @throws \Exception
180
     */
181
    protected function getPreparedInvoiceData(): array
182
    {
183
        if (empty($this->preparedData)) {
184
            $this->preparedData = $this->prepareInvoiceData();
185
        }
186
187
        return $this->preparedData;
188
    }
189
190
    /**
191
     * Prepare invoice data
192
     *
193
     * @return array
194
     * @throws \Exception
195
     */
196
    protected function prepareInvoiceData(): array
197
    {
198
        $action = 8; // 8 : for buy request (bank standard)
199
        $terminalCode = $this->settings->terminalCode;
200
        $amount = $this->invoice->getAmount();
201
        $redirectAddress = $this->settings->callbackUrl;
202
        $invoiceNumber = crc32($this->invoice->getUuid()) . rand(0, time());
203
204
        $iranTime = new DateTime('now', new DateTimeZone('Asia/Tehran'));
205
        $invoiceDate = $iranTime->format("Y/m/d H:i:s");
206
207
        if (!empty($this->invoice->getDetails()['date'])) {
208
            $invoiceDate = $this->invoice->getDetails()['date'];
209
        }
210
211
        return [
212
            'invoice' => $invoiceNumber,
213
            'invoiceDate' => $invoiceDate,
214
            'amount' => $amount,
215
            'terminalNumber' => $terminalCode,
216
            'callbackApi' => $redirectAddress,
217
            'serviceCode' => $action,
218
            'nationalCode' => "",
219
            'serviceType' => "PURCHASE",
220
            'mobileNumber' => ""
221
        ];
222
    }
223
224
    /**
225
     * Make request to pasargad's Api
226
     *
227
     * @param string $url
228
     * @param array $body
229
     * @param string $method
230
     * @param string|null $token
231
     * @return array
232
     * @throws GuzzleException
233
     * @throws InvalidPaymentException
234
     */
235
    protected function request(string $url, array $body, string $method = 'POST', string $token = null): array
0 ignored issues
show
Unused Code introduced by
The parameter $method 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

235
    protected function request(string $url, array $body, /** @scrutinizer ignore-unused */ string $method = 'POST', string $token = null): array

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...
236
    {
237
        $body = json_encode($body);
238
        $token = $token != null ? 'Bearer '.$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...
239
240
        $response = $this->client->request(
241
            'POST',
242
            $url,
243
            [
244
                'body' => $body,
245
                'headers' => [
246
                    'content-type' => 'application/json',
247
                    'Authorization' => $token
248
                ],
249
                "http_errors" => false,
250
            ]
251
        );
252
253
        $result = json_decode($response->getBody(), true);
254
255
        if ($result['resultMsg'] !== 'Successful') {
256
            throw new InvalidPaymentException($result['resultMsg']);
257
        }
258
259
        return $result;
260
    }
261
262
    /**
263
     * * make token with username and password
264
     * @return string
265
     * @throws InvalidPaymentException
266
     */
267
    protected function createToken(): string
268
    {
269
        $data = [
270
            "username" => $this->settings->username,
271
            "password" => $this->settings->password
272
        ];
273
274
        $getTokenUrl = $this->settings->apiGetToken;
275
276
        try {
277
            return $this->request(
278
                $getTokenUrl,
279
                $data
280
            )['token'];
281
        } catch (GuzzleException|InvalidPaymentException $e) {
282
            throw new InvalidPaymentException($e->getMessage());
283
        }
284
    }
285
}
286