Payir   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 80
c 2
b 1
f 0
dl 0
loc 197
rs 10
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A extractDetails() 0 3 2
A verify() 0 26 3
A createReceipt() 0 5 1
A pay() 0 5 1
A notVerified() 0 36 2
A purchase() 0 35 3
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Payir;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
8
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
9
use Shetabit\Multipay\Contracts\ReceiptInterface;
10
use Shetabit\Multipay\Invoice;
11
use Shetabit\Multipay\Receipt;
12
use Shetabit\Multipay\RedirectionForm;
13
use Shetabit\Multipay\Request;
14
15
class Payir extends Driver
16
{
17
    /**
18
     * Payir 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
     * Payir 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
     * @throws \GuzzleHttp\Exception\GuzzleException
69
     */
70
    public function purchase()
71
    {
72
        $mobile = $this->extractDetails('mobile');
73
        $description = $this->extractDetails('description');
74
        $validCardNumber = $this->extractDetails('validCardNumber');
75
76
        $data = array(
77
            'api' => $this->settings->merchantId,
78
            'amount' => $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1), // convert to rial
79
            'redirect' => $this->settings->callbackUrl,
80
            'mobile' => $mobile,
81
            'description' => $description,
82
            'factorNumber' => $this->invoice->getUuid(),
83
            'validCardNumber' => $validCardNumber
84
        );
85
86
        $response = $this->client->request(
87
            'POST',
88
            $this->settings->apiPurchaseUrl,
89
            [
90
                "form_params" => $data,
91
                "http_errors" => false,
92
            ]
93
        );
94
        $body = json_decode($response->getBody()->getContents(), true);
95
96
        if ($body['status'] != 1) {
97
            // some error has happened
98
            throw new PurchaseFailedException($body['errorMessage']);
99
        }
100
101
        $this->invoice->transactionId($body['token']);
102
103
        // return the transaction's id
104
        return $this->invoice->getTransactionId();
105
    }
106
107
    /**
108
     * Pay the Invoice
109
     *
110
     * @return RedirectionForm
111
     */
112
    public function pay(): RedirectionForm
113
    {
114
        $payUrl = $this->settings->apiPaymentUrl . $this->invoice->getTransactionId();
115
116
        return $this->redirectWithForm($payUrl, [], 'GET');
117
    }
118
119
    /**
120
     * Verify payment
121
     *
122
     * @return ReceiptInterface
123
     *
124
     * @throws InvalidPaymentException
125
     * @throws \GuzzleHttp\Exception\GuzzleException
126
     */
127
    public function verify(): ReceiptInterface
128
    {
129
        $data = [
130
            'api' => $this->settings->merchantId,
131
            'token'  => $this->invoice->getTransactionId() ?? Request::input('token'),
132
        ];
133
134
        $response = $this->client->request(
135
            'POST',
136
            $this->settings->apiVerificationUrl,
137
            [
138
                "form_params" => $data,
139
                "http_errors" => false,
140
            ]
141
        );
142
        $body = json_decode($response->getBody()->getContents(), true);
143
144
        if (isset($body['status'])) {
145
            if ($body['status'] != 1) {
146
                $this->notVerified($body['errorCode']);
147
            }
148
        } else {
149
            $this->notVerified(null);
150
        }
151
152
        return $this->createReceipt($body['transId']);
153
    }
154
155
    /**
156
     * Generate the payment's receipt
157
     *
158
     * @param $referenceId
159
     *
160
     * @return Receipt
161
     */
162
    protected function createReceipt($referenceId)
163
    {
164
        $receipt = new Receipt('payir', $referenceId);
165
166
        return $receipt;
167
    }
168
169
    /**
170
     * Trigger an exception
171
     *
172
     * @param $status
173
     *
174
     * @throws InvalidPaymentException
175
     */
176
    private function notVerified($status)
177
    {
178
        $translations = array(
179
            0 => 'درحال حاضر درگاه بانکی قطع شده و مشکل بزودی برطرف می شود',
180
            -1 => 'API Key ارسال نمی شود',
181
            -2 => 'Token ارسال نمی شود',
182
            -3 => 'API Key ارسال شده اشتباه است',
183
            -4 => 'امکان انجام تراکنش برای این پذیرنده وجود ندارد',
184
            -5 => 'تراکنش با خطا مواجه شده است',
185
            -6 => 'تراکنش تکراریست یا قبلا انجام شده',
186
            -7 => 'مقدار Token ارسالی اشتباه است',
187
            -8 => 'شماره تراکنش ارسالی اشتباه است',
188
            -9 => 'زمان مجاز برای انجام تراکنش تمام شده',
189
            -10 => 'مبلغ تراکنش ارسال نمی شود',
190
            -11 => 'مبلغ تراکنش باید به صورت عددی و با کاراکترهای لاتین باشد',
191
            -12 => 'مبلغ تراکنش می بایست عددی بین 10,000 و 500,000,000 ریال باشد',
192
            -13 => 'مقدار آدرس بازگشتی ارسال نمی شود',
193
            -14 => 'آدرس بازگشتی ارسالی با آدرس درگاه ثبت شده در شبکه پرداخت پی یکسان نیست',
194
            -15 => 'امکان وریفای وجود ندارد. این تراکنش پرداخت نشده است',
195
            -16 => 'یک یا چند شماره موبایل از اطلاعات پذیرندگان ارسال شده اشتباه است',
196
            -17 => 'میزان سهم ارسالی باید بصورت عددی و بین 1 تا 100 باشد',
197
            -18 => 'فرمت پذیرندگان صحیح نمی باشد',
198
            -19 => 'هر پذیرنده فقط یک سهم میتواند داشته باشد',
199
            -20 => 'مجموع سهم پذیرنده ها باید 100 درصد باشد',
200
            -21 => 'Reseller ID ارسالی اشتباه است',
201
            -22 => 'فرمت یا طول مقادیر ارسالی به درگاه اشتباه است',
202
            -23 => 'سوییچ PSP ( درگاه بانک ) قادر به پردازش درخواست نیست. لطفا لحظاتی بعد مجددا تلاش کنید',
203
            -24 => 'شماره کارت باید بصورت 16 رقمی، لاتین و چسبیده بهم باشد',
204
            -25 => 'امکان استفاده از سرویس در کشور مبدا شما وجود نداره',
205
            -26 => 'امکان انجام تراکنش برای این درگاه وجود ندارد',
206
        );
207
208
        if (array_key_exists($status, $translations)) {
209
            throw new InvalidPaymentException($translations[$status], (int)$status);
210
        } else {
211
            throw new InvalidPaymentException('تراکنش با خطا مواجه شد.', (int)$status);
212
        }
213
    }
214
}
215