Passed
Push — master ( aebca7...670177 )
by mahdi
02:43
created

Zarinpal::translateStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

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