Idpay::purchase()   B
last analyzed

Complexity

Conditions 9
Paths 108

Size

Total Lines 63
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 42
c 1
b 0
f 0
nc 108
nop 0
dl 0
loc 63
rs 7.6391

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\Multipay\Drivers\Idpay;
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 Idpay extends Driver
16
{
17
    /**
18
     * Idpay 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
     * Idpay 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 \GuzzleHttp\Exception\GuzzleException
59
     */
60
    public function purchase()
61
    {
62
        $details = $this->invoice->getDetails();
63
64
        $phone = null;
65
        if (!empty($details['phone'])) {
66
            $phone = $details['phone'];
67
        } elseif (!empty($details['mobile'])) {
68
            $phone = $details['mobile'];
69
        }
70
71
        $mail = null;
72
        if (!empty($details['mail'])) {
73
            $mail = $details['mail'];
74
        } elseif (!empty($details['email'])) {
75
            $mail = $details['email'];
76
        }
77
78
        $desc = $this->settings->description;
79
        if (!empty($details['desc'])) {
80
            $desc = $details['desc'];
81
        } elseif (!empty($details['description'])) {
82
            $desc = $details['description'];
83
        }
84
85
        $data = array(
86
            'order_id' => $this->invoice->getUuid(),
87
            'amount' => $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1), // convert to rial
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 RedirectionForm
129
     */
130
    public function pay() : RedirectionForm
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
        return $this->redirectWithForm($payUrl, [], 'GET');
142
    }
143
144
    /**
145
     * Verify payment
146
     *
147
     * @return mixed|void
148
     *
149
     * @throws InvalidPaymentException
150
     * @throws \GuzzleHttp\Exception\GuzzleException
151
     */
152
    public function verify() : ReceiptInterface
153
    {
154
        $data = [
155
            'id' => $this->invoice->getTransactionId() ?? Request::input('id'),
156
            'order_id' => Request::input('order_id'),
157
        ];
158
159
        $response = $this->client->request(
160
            'POST',
161
            $this->settings->apiVerificationUrl,
162
            [
163
                'json' => $data,
164
                "headers" => [
165
                    'X-API-KEY' => $this->settings->merchantId,
166
                    'Content-Type' => 'application/json',
167
                    'X-SANDBOX' => (int) $this->settings->sandbox,
168
                ],
169
                "http_errors" => false,
170
            ]
171
        );
172
        $body = json_decode($response->getBody()->getContents(), true);
173
174
        if (isset($body['error_code']) || $body['status'] != 100) {
175
            $errorCode = $body['status'] ?? $body['error_code'];
176
177
            $this->notVerified($errorCode);
178
        }
179
180
        $receipt = $this->createReceipt($body['track_id']);
181
        $receipt->detail($body);
182
183
        return $receipt;
184
    }
185
186
    /**
187
     * Generate the payment's receipt
188
     *
189
     * @param $referenceId
190
     *
191
     * @return Receipt
192
     */
193
    protected function createReceipt($referenceId)
194
    {
195
        $receipt = new Receipt('idpay', $referenceId);
196
197
        return $receipt;
198
    }
199
200
    /**
201
     * Trigger an exception
202
     *
203
     * @param $status
204
     *
205
     * @throws InvalidPaymentException
206
     */
207
    private function notVerified($status)
208
    {
209
        $translations = array(
210
            "1" => "پرداخت انجام نشده است.",
211
            "2" => "پرداخت ناموفق بوده است.",
212
            "3" => "خطا رخ داده است.",
213
            "4" => "بلوکه شده.",
214
            "5" => "برگشت به پرداخت کننده.",
215
            "6" => "برگشت خورده سیستمی.",
216
            "10" => "در انتظار تایید پرداخت.",
217
            "100" => "پرداخت تایید شده است.",
218
            "101" => "پرداخت قبلا تایید شده است.",
219
            "200" => "به دریافت کننده واریز شد.",
220
            "11" => "کاربر مسدود شده است.",
221
            "12" => "API Key یافت نشد.",
222
            "13" => "درخواست شما از {ip} ارسال شده است. این IP با IP های ثبت شده در وب سرویس همخوانی ندارد.",
223
            "14" => "وب سرویس تایید نشده است.",
224
            "21" => "حساب بانکی متصل به وب سرویس تایید نشده است.",
225
            "31" => "کد تراکنش id نباید خالی باشد.",
226
            "32" => "شماره سفارش order_id نباید خالی باشد.",
227
            "33" => "مبلغ amount نباید خالی باشد.",
228
            "34" => "مبلغ amount باید بیشتر از {min-amount} ریال باشد.",
229
            "35" => "مبلغ amount باید کمتر از {max-amount} ریال باشد.",
230
            "36" => "مبلغ amount بیشتر از حد مجاز است.",
231
            "37" => "آدرس بازگشت callback نباید خالی باشد.",
232
            "38" => "درخواست شما از آدرس {domain} ارسال شده است. دامنه آدرس بازگشت callback با آدرس ثبت شده در وب سرویس همخوانی ندارد.",
233
            "51" => "تراکنش ایجاد نشد.",
234
            "52" => "استعلام نتیجه ای نداشت.",
235
            "53" => "تایید پرداخت امکان پذیر نیست.",
236
            "54" => "مدت زمان تایید پرداخت سپری شده است.",
237
        );
238
        if (array_key_exists($status, $translations)) {
239
            throw new InvalidPaymentException($translations[$status], (int)$status);
240
        } else {
241
            throw new InvalidPaymentException('خطای ناشناخته ای رخ داده است.', (int)$status);
242
        }
243
    }
244
}
245