Passed
Push — master ( 6a7137...bf4170 )
by mahdi
07:53
created

Normal::translateStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 23
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 28
rs 9.552
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Zarinpal\Strategies;
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 Normal 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
     * Zarinpal 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
     * Purchase Invoice.
54
     *
55
     * @return string
56
     *
57
     * @throws PurchaseFailedException
58
     * @throws \SoapFault
59
     */
60
    public function purchase()
61
    {
62
        $metadata = [];
63
64
        if (!empty($this->invoice->getDetails()['description'])) {
65
            $description = $this->invoice->getDetails()['description'];
66
        } else {
67
            $description = $this->settings->description;
68
        }
69
70
        if (!empty($this->invoice->getDetails()['mobile'])) {
71
            $metadata['mobile'] = $this->invoice->getDetails()['mobile'];
72
        }
73
74
        if (!empty($this->invoice->getDetails()['email'])) {
75
            $metadata['email'] = $this->invoice->getDetails()['email'];
76
        }
77
78
        $data = [
79
            "merchant_id" => $this->settings->merchantId,
80
            "amount" => $this->invoice->getAmount() * 10, // convert toman to rial
81
            "callback_url" => $this->settings->callbackUrl,
82
            "description" => $description,
83
            "metadata" => array_merge($this->invoice->getDetails() ?? [], $metadata),
84
        ];
85
86
        $response = $this
87
            ->client
88
            ->request(
89
                'POST',
90
                $this->settings->apiPurchaseUrl,
91
                [
92
                    "json" => $data,
93
                    "headers" => [
94
                        'Content-Type' => 'application/json',
95
                    ],
96
                    "http_errors" => false,
97
                ]
98
            );
99
100
        $result = json_decode($response->getBody()->getContents(), true);
101
102
        if (!empty($result['errors']) || empty($result['data']) || $result['data']['code'] != 100) {
103
            $bodyResponse = $result['errors']['code'];
104
            throw new PurchaseFailedException($this->translateStatus($bodyResponse), $bodyResponse);
105
        }
106
107
        $this->invoice->transactionId($result['data']["authority"]);
108
109
        // return the transaction's id
110
        return $this->invoice->getTransactionId();
111
    }
112
113
    /**
114
     * Pay the Invoice
115
     *
116
     * @return RedirectionForm
117
     */
118
    public function pay(): RedirectionForm
119
    {
120
        $transactionId = $this->invoice->getTransactionId();
121
        $paymentUrl = $this->getPaymentUrl();
122
123
        $payUrl = $paymentUrl . $transactionId;
124
125
        return $this->redirectWithForm($payUrl, [], 'GET');
126
    }
127
128
    /**
129
     * Verify payment
130
     *
131
     * @return ReceiptInterface
132
     *
133
     * @throws InvalidPaymentException
134
     */
135
    public function verify(): ReceiptInterface
136
    {
137
        $authority = $this->invoice->getTransactionId() ?? Request::input('Authority');
138
        $data = [
139
            "merchant_id" => $this->settings->merchantId,
140
            "authority" => $authority,
141
            "amount" => $this->invoice->getAmount() * 10, // convert toman to rial
142
        ];
143
144
        $response = $this->client->request(
145
            'POST',
146
            $this->getVerificationUrl(),
147
            [
148
                'json' => $data,
149
                "headers" => [
150
                    'Content-Type' => 'application/json',
151
                ],
152
                "http_errors" => false,
153
            ]
154
        );
155
156
        $result = json_decode($response->getBody()->getContents(), true);
157
158
        if (empty($result['data']) || !isset($result['data']['ref_id']) || ($result['data']['code'] != 100 && $result['data']['code'] != 101)) {
159
            $bodyResponse = $result['errors']['code'];
160
            throw new InvalidPaymentException($this->translateStatus($bodyResponse), $bodyResponse);
161
        }
162
163
        $bodyResponse = $result['data']['code'];
164
        if ($bodyResponse == 101) {
165
            throw new InvalidPaymentException($this->translateStatus($bodyResponse), $bodyResponse);
166
        }
167
168
        return $this->createReceipt($result['data']['ref_id']);
169
    }
170
171
    /**
172
     * Generate the payment's receipt
173
     *
174
     * @param $referenceId
175
     *
176
     * @return Receipt
177
     */
178
    public function createReceipt($referenceId)
179
    {
180
        return new Receipt('zarinpal', $referenceId);
181
    }
182
183
    /**
184
     * Retrieve purchase url
185
     *
186
     * @return string
187
     */
188
    protected function getPurchaseUrl(): string
189
    {
190
        return $this->settings->apiPurchaseUrl;
191
    }
192
193
    /**
194
     * Retrieve Payment url
195
     *
196
     * @return string
197
     */
198
    protected function getPaymentUrl(): string
199
    {
200
        return $this->settings->apiPaymentUrl;
201
    }
202
203
    /**
204
     * Retrieve verification url
205
     *
206
     * @return string
207
     */
208
    protected function getVerificationUrl(): string
209
    {
210
        return $this->settings->apiVerificationUrl;
211
    }
212
213
    /**
214
     * Convert status to a readable message.
215
     *
216
     * @param $status
217
     *
218
     * @return mixed|string
219
     */
220
    private function translateStatus($status)
221
    {
222
        $translations = [
223
            '100' => 'تراکنش با موفقیت انجام گردید',
224
            '101' => 'عمليات پرداخت موفق بوده و قبلا عملیات وریفای تراكنش انجام شده است',
225
            '-9' => 'خطای اعتبار سنجی',
226
            '-10' => 'ای پی و يا مرچنت كد پذيرنده صحيح نمی باشد',
227
            '-11' => 'مرچنت کد فعال نیست لطفا با تیم پشتیبانی ما تماس بگیرید',
228
            '-12' => 'تلاش بیش از حد در یک بازه زمانی کوتاه',
229
            '-15' => 'ترمینال شما به حالت تعلیق در آمده با تیم پشتیبانی تماس بگیرید',
230
            '-16' => 'سطح تاييد پذيرنده پايين تر از سطح نقره ای می باشد',
231
            '-30' => 'اجازه دسترسی به تسویه اشتراکی شناور ندارید',
232
            '-31' => 'حساب بانکی تسویه را به پنل اضافه کنید مقادیر وارد شده برای تسهیم صحيح نمی باشد',
233
            '-32' => 'مقادیر وارد شده برای تسهیم صحيح نمی باشد',
234
            '-33' => 'درصد های وارد شده صحيح نمی باشد',
235
            '-34' => 'مبلغ از کل تراکنش بیشتر است',
236
            '-35' => 'تعداد افراد دریافت کننده تسهیم بیش از حد مجاز است',
237
            '-40' => 'پارامترهای اضافی نامعتبر، expire_in معتبر نیست',
238
            '-50' => 'مبلغ پرداخت شده با مقدار مبلغ در وریفای متفاوت است',
239
            '-51' => 'پرداخت ناموفق',
240
            '-52' => 'خطای غیر منتظره با پشتیبانی تماس بگیرید',
241
            '-53' => 'اتوریتی برای این مرچنت کد نیست',
242
            '-54' => 'اتوریتی نامعتبر است',
243
        ];
244
245
        $unknownError = 'خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد';
246
247
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
248
    }
249
}
250