Passed
Push — master ( 4dacf8...c622ff )
by mahdi
02:43
created

Idpay::purchase()   B

Complexity

Conditions 8
Paths 54

Size

Total Lines 65
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 44
c 1
b 0
f 0
dl 0
loc 65
rs 7.9715
cc 8
nc 54
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Shetabit\Payment\Drivers\Idpay;
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 Idpay extends Driver
14
{
15
    /**
16
     * Idpay 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
     * Idpay 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 \GuzzleHttp\Exception\GuzzleException
57
     */
58
    public function purchase()
59
    {
60
        $details = $this->invoice->getDetails();
61
62
        $phone = null;
63
        if (!empty($details['phone'])) {
64
            $phone = $details['phone'];
65
        } else if (!empty($details['mobile'])) {
66
            $phone = $details['mobile'];
67
        }
68
69
        $mail = null;
70
        if (!empty($details['mail'])) {
71
            $mail = $details['mail'];
72
        } else if (!empty($details['email'])) {
73
            $mail = $details['email'];
74
        }
75
76
        $desc = null;
77
        if (!empty($details['desc'])) {
78
            $desc = $details['desc'];
79
        } else if (!empty($details['description'])) {
80
            $desc = $details['description'];
81
        } else {
82
            $desc = $this->settings->description;
83
        }
84
85
        $data = array(
86
            'order_id' => $this->invoice->getUuid(),
87
            'amount' => $this->invoice->getAmount(),
88
            'name' => $details['name'] ?? null,
89
            'phone' => $phone,
90
            'mail' => $mail,
91
            'desc' => $desc,
92
            'callback' => $this->settings->callbackUrl,
93
            'reseller' => $details['reseller'] ?? null,
94
        );
95
96
        $response = $this
97
            ->client
98
            ->request(
99
                'POST',
100
                $this->settings->apiPurchaseUrl,
101
                [
102
                    "json" => $data,
103
                    "headers" => [
104
                        'X-API-KEY' => $this->settings->merchantId,
105
                        'Content-Type' => 'application/json',
106
                        'X-SANDBOX' => (int) $this->settings->sandbox,
107
                    ],
108
                    "http_errors" => false,
109
                ]
110
            );
111
112
        $body = json_decode($response->getBody()->getContents(), true);
113
        if (empty($body['id'])) {
114
            // error has happened
115
            $message = $body['error_message'] ?? 'خطا در هنگام درخواست برای پرداخت رخ داده است.';
116
            throw new PurchaseFailedException($message);
117
        }
118
119
        $this->invoice->transactionId($body['id']);
120
121
        // return the transaction's id
122
        return $this->invoice->getTransactionId();
123
    }
124
125
    /**
126
     * Pay the Invoice
127
     *
128
     * @return \Illuminate\Http\RedirectResponse|mixed
129
     */
130
    public function pay()
131
    {
132
        $apiUrl = $this->settings->apiPaymentUrl;
133
134
        // use sandbox url if we are in sandbox mode
135
        if (!empty($this->settings->sandbox)) {
136
            $apiUrl = $this->settings->apiSandboxPaymentUrl;
137
        }
138
139
        $payUrl = $apiUrl.$this->invoice->getTransactionId();
140
141
        // redirect using laravel logic
142
        return redirect()->to($payUrl);
143
    }
144
145
    /**
146
     * Verify payment
147
     *
148
     * @return mixed|void
149
     *
150
     * @throws InvalidPaymentException
151
     * @throws \GuzzleHttp\Exception\GuzzleException
152
     */
153
    public function verify() : ReceiptInterface
154
    {
155
        $data = [
156
            'id' => $this->invoice->getTransactionId() ?? request()->input('id'),
157
            'order_id' => request()->input('order_id'),
158
        ];
159
160
        $response = $this->client->request(
161
            'POST',
162
            $this->settings->apiVerificationUrl,
163
            [
164
                'json' => $data,
165
                "headers" => [
166
                    'X-API-KEY' => $this->settings->merchantId,
167
                    'Content-Type' => 'application/json',
168
                    'X-SANDBOX' => (int) $this->settings->sandbox,
169
                ],
170
                "http_errors" => false,
171
            ]
172
        );
173
        $body = json_decode($response->getBody()->getContents(), true);
174
175
        if (isset($body['error_code']) || $body['status'] != 100) {
176
            $errorCode = $body['status'] ?? $body['error_code'];
177
178
            $this->notVerified($errorCode);
179
        }
180
181
        return $this->createReceipt($body['track_id']);
182
    }
183
184
    /**
185
     * Generate the payment's receipt
186
     *
187
     * @param $referenceId
188
     *
189
     * @return Receipt
190
     */
191
    protected function createReceipt($referenceId)
192
    {
193
        $receipt = new Receipt('idpay', $referenceId);
194
195
        return $receipt;
196
    }
197
198
    /**
199
     * Trigger an exception
200
     *
201
     * @param $status
202
     *
203
     * @throws InvalidPaymentException
204
     */
205
    private function notVerified($status)
206
    {
207
        $translations = array(
208
            "1" => "پرداخت انجام نشده است.",
209
            "2" => "پرداخت ناموفق بوده است.",
210
            "3" => "خطا رخ داده است.",
211
            "4" => "بلوکه شده.",
212
            "5" => "برگشت به پرداخت کننده.",
213
            "6" => "برگشت خورده سیستمی.",
214
            "10" => "در انتظار تایید پرداخت.",
215
            "100" => "پرداخت تایید شده است.",
216
            "101" => "پرداخت قبلا تایید شده است.",
217
            "200" => "به دریافت کننده واریز شد.",
218
            "11" => "کاربر مسدود شده است.",
219
            "12" => "API Key یافت نشد.",
220
            "13" => "درخواست شما از {ip} ارسال شده است. این IP با IP های ثبت شده در وب سرویس همخوانی ندارد.",
221
            "14" => "وب سرویس تایید نشده است.",
222
            "21" => "حساب بانکی متصل به وب سرویس تایید نشده است.",
223
            "31" => "کد تراکنش id نباید خالی باشد.",
224
            "32" => "شماره سفارش order_id نباید خالی باشد.",
225
            "33" => "مبلغ amount نباید خالی باشد.",
226
            "34" => "مبلغ amount باید بیشتر از {min-amount} ریال باشد.",
227
            "35" => "مبلغ amount باید کمتر از {max-amount} ریال باشد.",
228
            "36" => "مبلغ amount بیشتر از حد مجاز است.",
229
            "37" => "آدرس بازگشت callback نباید خالی باشد.",
230
            "38" => "درخواست شما از آدرس {domain} ارسال شده است. دامنه آدرس بازگشت callback با آدرس ثبت شده در وب سرویس همخوانی ندارد.",
231
            "51" => "تراکنش ایجاد نشد.",
232
            "52" => "استعلام نتیجه ای نداشت.",
233
            "53" => "تایید پرداخت امکان پذیر نیست.",
234
            "54" => "مدت زمان تایید پرداخت سپری شده است.",
235
        );
236
        if (array_key_exists($status, $translations)) {
237
            throw new InvalidPaymentException($translations[$status]);
238
        } else {
239
            throw new InvalidPaymentException('خطای ناشناخته ای رخ داده است.');
240
        }
241
    }
242
}
243