Passed
Push — master ( 437f23...0ad4c0 )
by mahdi
03:18
created

Zarinpal   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 23
eloc 102
dl 0
loc 257
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A notVerified() 0 23 2
A verify() 0 24 3
A getVerificationUrl() 0 17 3
A getPurchaseUrl() 0 17 3
A getMode() 0 3 1
A purchase() 0 29 4
A __construct() 0 5 1
A createReceipt() 0 5 1
A pay() 0 13 2
A getPaymentUrl() 0 17 3
1
<?php
2
3
namespace Shetabit\Payment\Drivers\Zarinpal;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Payment\Abstracts\Driver;
7
use Shetabit\Payment\Exceptions\{InvalidPaymentException, PurchaseFailedException};
8
use Shetabit\Payment\{Contracts\ReceiptInterface, Invoice, Receipt};
9
10
class Zarinpal extends Driver
11
{
12
    /**
13
     * Zarinpal Client.
14
     *
15
     * @var object
16
     */
17
    protected $client;
18
19
    /**
20
     * Invoice
21
     *
22
     * @var Invoice
23
     */
24
    protected $invoice;
25
26
    /**
27
     * Driver settings
28
     *
29
     * @var object
30
     */
31
    protected $settings;
32
33
    /**
34
     * Zarinpal constructor.
35
     * Construct the class with the relevant settings.
36
     *
37
     * @param Invoice $invoice
38
     * @param $settings
39
     */
40
    public function __construct(Invoice $invoice, $settings)
41
    {
42
        $this->invoice($invoice);
43
        $this->settings = (object)$settings;
44
        $this->client = new Client();
45
    }
46
47
    /**
48
     * Purchase Invoice.
49
     *
50
     * @return string
51
     *
52
     * @throws PurchaseFailedException
53
     * @throws \SoapFault
54
     */
55
    public function purchase()
56
    {
57
        if (!empty($this->invoice->getDetails()['description'])) {
58
            $description = $this->invoice->getDetails()['description'];
59
        } else {
60
            $description = $this->settings->description;
61
        }
62
63
        $data = array(
64
            'MerchantID' => $this->settings->merchantId,
65
            'Amount' => $this->invoice->getAmount(),
66
            'CallbackURL' => $this->settings->callbackUrl,
67
            'Description' => $description,
68
            'AdditionalData' => $this->invoice->getDetails()
69
        );
70
71
        $client = new \SoapClient($this->getPurchaseUrl(), ['encoding' => 'UTF-8']);
72
73
        $result = $client->PaymentRequest($data);
74
75
        if ($result->Status != 100 || empty($body['Authority'])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $body seems to never exist and therefore empty should always be true.
Loading history...
76
            // some error has happened
77
            throw new PurchaseFailedException('خطا در هنگام درخواست برای پرداخت رخ داده است.');
78
        }
79
80
        $this->invoice->transactionId($result->Authority);
81
82
        // return the transaction's id
83
        return $this->invoice->getTransactionId();
84
    }
85
86
    /**
87
     * Pay the Invoice
88
     *
89
     * @return \Illuminate\Http\RedirectResponse|mixed
90
     */
91
    public function pay()
92
    {
93
        $transactionId = $this->invoice->getTransactionId();
94
        $paymentUrl = $this->getPaymentUrl();
95
96
        if (strtolower($this->getMode()) == 'zaringate') {
97
            $payUrl = str_replace(':authority', $transactionId, $paymentUrl);
98
        } else {
99
            $payUrl = $paymentUrl . $transactionId;
100
        }
101
102
        // redirect using laravel logic
103
        return redirect()->to($payUrl);
104
    }
105
106
    /**
107
     * Verify payment
108
     *
109
     * @return mixed|void
110
     *
111
     * @throws InvalidPaymentException
112
     * @throws \GuzzleHttp\Exception\GuzzleException
113
     */
114
    public function verify() : ReceiptInterface
115
    {
116
        $authority = $this->invoice->getTransactionId() ?? request()->get('Authority');
117
        $status = request()->get('Status');
118
119
        $data = [
120
            'MerchantID' => $this->settings->merchantId,
121
            'Authority' => $authority,
122
            'Amount' => $this->invoice->getAmount(),
123
        ];
124
125
        if ($status != 'OK') {
126
            throw new InvalidPaymentException('عملیات پرداخت توسط کاربر لغو شد.');
127
        }
128
129
        $client = new SoapClient('https://zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);
0 ignored issues
show
Bug introduced by
The type Shetabit\Payment\Drivers\Zarinpal\SoapClient was not found. Did you mean SoapClient? If so, make sure to prefix the type with \.
Loading history...
130
131
        $result = $client->PaymentVerification($data);
132
133
        if ($result->Status != 100) {
134
            $this->notVerified($result->Status);
135
        }
136
137
        return $this->createReceipt($result->RefID);
138
    }
139
140
    /**
141
     * Generate the payment's receipt
142
     *
143
     * @param $referenceId
144
     *
145
     * @return Receipt
146
     */
147
    public function createReceipt($referenceId)
148
    {
149
        $receipt = new Receipt('zarinpal', $referenceId);
150
151
        return $receipt;
152
    }
153
154
    /**
155
     * Trigger an exception
156
     *
157
     * @param $status
158
     *
159
     * @throws InvalidPaymentException
160
     */
161
    private function notVerified($status)
162
    {
163
        $translations = array(
164
            "-1" => "اطلاعات ارسال شده ناقص است.",
165
            "-2" => "IP و يا مرچنت كد پذيرنده صحيح نيست",
166
            "-3" => "با توجه به محدوديت هاي شاپرك امكان پرداخت با رقم درخواست شده ميسر نمي باشد",
167
            "-4" => "سطح تاييد پذيرنده پايين تر از سطح نقره اي است.",
168
            "-11" => "درخواست مورد نظر يافت نشد.",
169
            "-12" => "امكان ويرايش درخواست ميسر نمي باشد.",
170
            "-21" => "هيچ نوع عمليات مالي براي اين تراكنش يافت نشد",
171
            "-22" => "تراكنش نا موفق ميباشد",
172
            "-33" => "رقم تراكنش با رقم پرداخت شده مطابقت ندارد",
173
            "-34" => "سقف تقسيم تراكنش از لحاظ تعداد يا رقم عبور نموده است",
174
            "-40" => "اجازه دسترسي به متد مربوطه وجود ندارد.",
175
            "-41" => "اطلاعات ارسال شده مربوط به AdditionalData غيرمعتبر ميباشد.",
176
            "-42" => "مدت زمان معتبر طول عمر شناسه پرداخت بايد بين 30 دقيه تا 45 روز مي باشد.",
177
            "-54" => "درخواست مورد نظر آرشيو شده است",
178
            "101" => "عمليات پرداخت موفق بوده و قبلا PaymentVerification تراكنش انجام شده است.",
179
        );
180
        if (array_key_exists($status, $translations)) {
181
            throw new InvalidPaymentException($translations[$status]);
182
        } else {
183
            throw new InvalidPaymentException('خطای ناشناخته ای رخ داده است.');
184
        }
185
    }
186
187
    /**
188
     * Retrieve purchase url
189
     *
190
     * @return string
191
     */
192
    protected function getPurchaseUrl() : string
193
    {
194
        $mode = $this->getMode();
195
196
        switch($mode) {
197
            case 'sandbox':
198
                $url = $this->settings->sandboxApiPurchaseUrl;
199
                break;
200
            case 'zaringate':
201
                $url = $this->settings->zaringateApiPurchaseUrl;
202
                break;
203
            default: // default: normal
204
                $url = $this->settings->apiPurchaseUrl;
205
                break;
206
        }
207
208
        return $url;
209
    }
210
211
    /**
212
     * Retrieve Payment url
213
     *
214
     * @return string
215
     */
216
    protected function getPaymentUrl() : string
217
    {
218
        $mode = $this->getMode();
219
220
        switch($mode) {
221
            case 'sandbox':
222
                $url = $this->settings->sandboxApiPaymentUrl;
223
                break;
224
            case 'zaringate':
225
                $url = $this->settings->zaringateApiPaymentUrl;
226
                break;
227
            default: // default: normal
228
                $url = $this->settings->apiPaymentUrl;
229
                break;
230
        }
231
232
        return $url;
233
    }
234
235
    /**
236
     * Retrieve verification url
237
     *
238
     * @return string
239
     */
240
    protected function getVerificationUrl() : string
241
    {
242
        $mode = $this->getMode();
243
244
        switch($mode) {
245
            case 'sandbox':
246
                $url = $this->settings->sandboxApiVerificationUrl;
247
                break;
248
            case 'zaringate':
249
                $url = $this->settings->zaringateApiVerificationUrl;
250
                break;
251
            default: // default: normal
252
                $url = $this->settings->apiVerificationUrl;
253
                break;
254
        }
255
256
        return $url;
257
    }
258
259
    /**
260
     * Retrieve payment mode.
261
     *
262
     * @return string
263
     */
264
    protected function getMode() : string
265
    {
266
        return strtolower($this->settings->mode);
267
    }
268
}
269