Passed
Push — master ( 65457a...6731a2 )
by mahdi
05:26 queued 02:33
created

IranDargah::getPurchaseUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
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 5
rs 10
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\IranDargah;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Contracts\ReceiptInterface;
8
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
9
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
10
use Shetabit\Multipay\Invoice;
11
use Shetabit\Multipay\Receipt;
12
use Shetabit\Multipay\RedirectionForm;
13
use Shetabit\Multipay\Request;
14
15
class IranDargah extends Driver
16
{
17
    /**
18
     * HTTP Client.
19
     *
20
     * @var object
21
     */
22
    protected $client;
23
24
    /**
25
     * Invoice
26
     *
27
     * @var Invoice
28
     */
29
    protected $invoice;
30
31
    /**
32
     * Driver settings
33
     *
34
     * @var object
35
     */
36
    protected $settings;
37
38
    /**
39
     * IranDargah constructor.
40
     * Construct the class with the relevant settings.
41
     *
42
     * @param Invoice $invoice
43
     * @param $settings
44
     */
45
    public function __construct(Invoice $invoice, $settings)
46
    {
47
        $this->invoice($invoice);
48
        $this->settings = (object) $settings;
49
        $this->client = new Client();
50
    }
51
52
    /**
53
     * Retrieve data from details using its name.
54
     *
55
     * @return string
56
     */
57
    private function extractDetails($name)
58
    {
59
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
60
    }
61
62
    /**
63
     * Purchase Invoice.
64
     *
65
     * @return string
66
     *
67
     * @throws PurchaseFailedException
68
     */
69
    public function purchase()
70
    {
71
        $data = [
72
            'merchantID' => $this->settings->merchantId,
73
            'amount' => $this->getInvoiceAmount(),
74
            'callbackURL' => $this->settings->callbackUrl,
75
            'orderId' => $this->invoice->getUuid(),
76
            'cardNumber' => $this->extractDetails('cardNumber'),
77
            'mobile' => $this->extractDetails('mobile'),
78
            'description' => $this->extractDetails('description'),
79
        ];
80
81
        $response = $this->client->request(
82
            'POST',
83
            $this->getPurchaseUrl(),
84
            [
85
                'form_params' => $data,
86
                'http_errors' => false,
87
            ]
88
        );
89
90
        $body = json_decode($response->getBody()->getContents(), true);
91
92
        if ($body['status'] != 200) {
93
            throw new PurchaseFailedException($this->translateStatus($body['status']), $body['status']);
94
        }
95
96
        $this->invoice->transactionId($body['authority']);
97
98
        // return the transaction's id
99
        return $this->invoice->getTransactionId();
100
    }
101
102
    /**
103
     * Pay the Invoice
104
     *
105
     * @return RedirectionForm
106
     */
107
    public function pay(): RedirectionForm
108
    {
109
        $payUrl = $this->getPaymentUrl() . $this->invoice->getTransactionId();
110
111
        return $this->redirectWithForm($payUrl, [], 'GET');
112
    }
113
114
    /**
115
     * Verify payment
116
     *
117
     * @return ReceiptInterface
118
     *
119
     * @throws InvalidPaymentException
120
     */
121
    public function verify(): ReceiptInterface
122
    {
123
        $paymentCode = Request::input('code');
124
125
        if ($paymentCode != 100) {
126
            throw new InvalidPaymentException($this->translateStatus($paymentCode), $paymentCode);
127
        }
128
129
        $data = [
130
            'merchantID' => $this->settings->merchantId,
131
            'authority' => $this->invoice->getTransactionId() ?? Request::input('authority'),
132
            'amount' => $this->getInvoiceAmount(),
133
            'orderId' => Request::input('orderId'),
134
        ];
135
136
        $response = $this->client->request(
137
            'POST',
138
            $this->getVerificationUrl(),
139
            [
140
                'json' => $data,
141
                "headers" => [
142
                    'Content-Type' => 'application/json',
143
                ],
144
                "http_errors" => false,
145
            ]
146
        );
147
148
        $body = json_decode($response->getBody()->getContents(), true);
149
150
        if ($body['status'] != 100) {
151
            throw new InvalidPaymentException($this->translateStatus($body['status']), $body['status']);
152
        }
153
154
        $refId = $body['refId'];
155
        $receipt =  $this->createReceipt($refId);
156
157
        $receipt->detail([
158
            'message' => $body['message'],
159
            'status' => $body['status'],
160
            'refId' => $refId,
161
            'orderId' => $body['orderId'],
162
            'cardNumber' => $body['cardNumber'],
163
        ]);
164
165
        return $receipt;
166
    }
167
168
    /**
169
     * Generate the payment's receipt
170
     *
171
     * @param $referenceId
172
     *
173
     * @return Receipt
174
     */
175
    public function createReceipt($referenceId)
176
    {
177
        return new Receipt('irandargah', $referenceId);
178
    }
179
180
    /**
181
     * Retrieve invoice amount
182
     *
183
     * @return int|float
184
     */
185
    protected function getInvoiceAmount()
186
    {
187
        return $this->invoice->getAmount() * (strtolower($this->settings->currency) === 't' ? 10 : 1); // convert to rial
188
    }
189
190
    /**
191
     * Retrieve purchase url
192
     *
193
     * @return string
194
     */
195
    protected function getPurchaseUrl(): string
196
    {
197
        return $this->isSandboxMode()
198
            ? $this->settings->sandboxApiPurchaseUrl
199
            : $this->settings->apiPurchaseUrl;
200
    }
201
202
    /**
203
     * Retrieve Payment url
204
     *
205
     * @return string
206
     */
207
    protected function getPaymentUrl(): string
208
    {
209
        return $this->isSandboxMode()
210
            ? $this->settings->sandboxApiPaymentUrl
211
            : $this->settings->apiPaymentUrl;
212
    }
213
214
    /**
215
     * Retrieve verification url
216
     *
217
     * @return string
218
     */
219
    protected function getVerificationUrl(): string
220
    {
221
        return $this->isSandboxMode()
222
            ? $this->settings->sandboxApiVerificationUrl
223
            : $this->settings->apiVerificationUrl;
224
    }
225
226
    /**
227
     * Retrieve payment in sandbox mode?
228
     *
229
     * @return bool
230
     */
231
    protected function isSandboxMode() : bool
232
    {
233
        return $this->settings->sandbox;
234
    }
235
236
    /**
237
     * Convert status to a readable message.
238
     *
239
     * @param $status
240
     *
241
     * @return mixed|string
242
     */
243
    private function translateStatus($status)
244
    {
245
        $translations = [
246
            '100' => 'تراکنش با موفقیت انجام ‌شده‌ است',
247
            '101' => 'تراکنش قبلا وریفای شده است',
248
            '200' => 'اتصال به درگاه بانک با موفقیت انجام ‌شده است',
249
            '201' => 'در حال پرداخت در درگاه بانک',
250
            '403' => 'کد مرچنت صحیح نمی‌باشد',
251
            '404' => 'تراکنش یافت نشد',
252
            '-1' => 'کاربر از انجام تراکنش منصرف‌ شده است',
253
            '-2' => 'اطلاعات ارسالی صحیح نمی‌باشد',
254
            '-10' => 'مبلغ تراکنش کمتر از ۱۰،۰۰۰ ریال است',
255
            '-11' => 'مبلغ تراکنش با مبلغ پرداخت، یکسان نیست. مبلغ برگشت خورد',
256
            '-12' => 'شماره کارتی که با آن، تراکنش انجام ‌شده است با شماره کارت ارسالی، مغایرت دارد. مبلغ برگشت خورد',
257
            '-13' => 'تراکنش تکراری است',
258
            '-20' => 'شناسه تراکنش یافت‌ نشد',
259
            '-21' => 'مدت زمان مجاز، جهت ارسال به بانک گذشته‌است',
260
            '-22' => 'تراکنش برای بانک ارسال شده است',
261
            '-23' => 'خطا در اتصال به درگاه بانک',
262
            '-30' => 'اشکالی در فرایند پرداخت ایجاد ‌شده است. مبلغ برگشت خورد',
263
            '-31' => 'خطای ناشناخته',
264
        ];
265
266
        $unknownError = 'خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد';
267
268
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
269
    }
270
}
271