Test Failed
Pull Request — master (#256)
by
unknown
04:44 queued 02:07
created

Pasargad::getDefaultExceptionMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
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['data']['url']
141
            ],
142
            'POST',
143
            $this->createToken()
144
        );
145
146
        if (!$verifyResult['data']['referenceNumber']) {
147
            throw new InvalidPaymentException("This transaction is fail.");
148
        }
149
150
        $receipt =  $this->createReceipt($$verifyResult['data']['referenceNumber']);
151
152
        $receipt->detail([
153
            'resultCode' => $verifyResult['resultCode'],
154
            'resultMsg' => $verifyResult['resultMsg'] ?? null,
155
            'hashedCardNumber' => $verifyResult['data']['hashedCardNumber'] ?? null,
156
            'maskedCardNumber' => $verifyResult['data']['maskedCardNumber'] ?? null,
157
            'invoiceId' => $transactionId,
158
            'referenceNumber' =>  $verifyResult['data']['referenceNumber'] ?? null,
159
            'trackId' =>  $verifyResult['data']['trackId'] ?? null,
160
            'amount' =>  $verifyResult['data']['amount'] ?? null,
161
            'requestDate' => $verifyResult['data']['requestDate'] ?? null,
162
        ]);
163
164
        return $receipt;
165
    }
166
167
168
    /**
169
     * Generate the payment's receipt
170
     *
171
     * @param $referenceId
172
     * @return Receipt
173
     */
174
    protected function createReceipt($referenceId): Receipt
175
    {
176
        return new Receipt('pasargad', $referenceId);
177
    }
178
179
    /**
180
     * Retrieve prepared invoice's data
181
     *
182
     * @return array
183
     * @throws \Exception
184
     */
185
    protected function getPreparedInvoiceData(): array
186
    {
187
        if (empty($this->preparedData)) {
188
            $this->preparedData = $this->prepareInvoiceData();
189
        }
190
191
        return $this->preparedData;
192
    }
193
194
    /**
195
     * Prepare invoice data
196
     *
197
     * @return array
198
     * @throws \Exception
199
     */
200
    protected function prepareInvoiceData(): array
201
    {
202
        $action = 8; // 8 : for buy request (bank standard)
203
        $terminalCode = $this->settings->terminalCode;
204
        $amount = $this->invoice->getAmount();
205
        $redirectAddress = $this->settings->callbackUrl;
206
        $invoiceNumber = crc32($this->invoice->getUuid()) . rand(0, time());
207
208
        $iranTime = new DateTime('now', new DateTimeZone('Asia/Tehran'));
209
        $invoiceDate = $iranTime->format("Y/m/d H:i:s");
210
211
        if (!empty($this->invoice->getDetails()['date'])) {
212
            $invoiceDate = $this->invoice->getDetails()['date'];
213
        }
214
215
        return [
216
            'invoice' => $invoiceNumber,
217
            'invoiceDate' => $invoiceDate,
218
            'amount' => $amount,
219
            'terminalNumber' => $terminalCode,
220
            'callbackApi' => $redirectAddress,
221
            'serviceCode' => $action,
222
            'nationalCode' => "",
223
            'serviceType' => "PURCHASE",
224
            'mobileNumber' => ""
225
        ];
226
    }
227
228
    /**
229
     * Make request to pasargad's Api
230
     *
231
     * @param string $url
232
     * @param array $body
233
     * @param string $method
234
     * @param string|null $token
235
     * @return array
236
     * @throws GuzzleException
237
     * @throws InvalidPaymentException
238
     */
239
    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

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