Passed
Push — master ( a02865...c1eb3e )
by mahdi
02:36
created

Payping::convertStatusCodeToMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 9
c 1
b 1
f 0
dl 0
loc 14
rs 9.9666
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Shetabit\Payment\Drivers\Payping;
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 Payping extends Driver
14
{
15
    /**
16
     * Payping 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
     * Payping 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
     * Retrieve data from details using its name.
52
     *
53
     * @return string
54
     */
55
    private function extractDetails($name)
56
    {
57
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
58
    }
59
60
    /**
61
     * Purchase Invoice.
62
     *
63
     * @return string
64
     *
65
     * @throws PurchaseFailedException
66
     * @throws \GuzzleHttp\Exception\GuzzleException
67
     */
68
    public function purchase()
69
    {
70
        $name = $this->extractDetails('name');
71
        $mobile = $this->extractDetails('mobile');
72
        $email = $this->extractDetails('email');
73
        $description = $this->extractDetails('description');
74
75
        $data = array(
76
            "payerName" => $name,
77
            "amount" => $this->invoice->getAmount(),
78
            "payerIdentity" => $mobile ?? $email,
79
            "returnUrl" => $this->settings->callbackUrl,
80
            "description" => $description,
81
            "clientRefId" => $this->invoice->getUuid(),
82
        );
83
84
        $response = $this
85
            ->client
86
            ->request(
87
                'POST',
88
                $this->settings->apiPurchaseUrl,
89
                [
90
                    "json" => $data,
91
                    "headers" => [
92
                        "Accept" => "application/json",
93
                        "Authorization" => "bearer ".$this->settings->merchantId,
94
                    ],
95
                    "http_errors" => false,
96
                ]
97
            );
98
99
        $responseBody = mb_strtolower($response->getBody()->getContents());
100
        $body = @json_decode($responseBody, true);
101
        $statusCode = (int) $response->getStatusCode();
102
103
        if ($statusCode !== 200) {
104
            // some error has happened
105
            $message = is_array($body) ? array_pop($body) : $this->convertStatusCodeToMessage($statusCode);
106
107
            throw new PurchaseFailedException($message);
108
        }
109
110
        $this->invoice->transactionId($body['code']);
111
112
        // return the transaction's id
113
        return $this->invoice->getTransactionId();
114
    }
115
116
    /**
117
     * Pay the Invoice
118
     *
119
     * @return \Illuminate\Http\RedirectResponse|mixed
120
     */
121
    public function pay()
122
    {
123
        $payUrl = $this->settings->apiPaymentUrl.$this->invoice->getTransactionId();
124
125
        // redirect using laravel logic
126
        return redirect()->to($payUrl);
127
    }
128
129
    /**
130
     * Verify payment
131
     *
132
     * @return ReceiptInterface
133
     *
134
     * @throws InvalidPaymentException
135
     * @throws \GuzzleHttp\Exception\GuzzleException
136
     */
137
    public function verify() : ReceiptInterface
138
    {
139
        $refId = request()->input('refid');
140
        $data = [
141
            'amount' => $this->invoice->getAmount(),
142
            'refId'  => $refId,
143
        ];
144
145
        $response = $this->client->request(
146
            'POST',
147
            $this->settings->apiVerificationUrl,
148
            [
149
                'json' => $data,
150
                "headers" => [
151
                    "Accept" => "application/json",
152
                    "Authorization" => "bearer ".$this->settings->merchantId,
153
                ],
154
                "http_errors" => false,
155
            ]
156
        );
157
158
        $responseBody = mb_strtolower($response->getBody()->getContents());
159
        $body = @json_decode($responseBody, true);
160
161
        $statusCode = (int) $response->getStatusCode();
162
163
        if ($statusCode !== 200) {
164
            $message = is_array($body) ? array_pop($body) : $this->convertStatusCodeToMessage($statusCode);
165
166
            $this->notVerified($message);
167
        }
168
169
        return $this->createReceipt($refId);
170
    }
171
172
    /**
173
     * Generate the payment's receipt
174
     *
175
     * @param $referenceId
176
     *
177
     * @return Receipt
178
     */
179
    protected function createReceipt($referenceId)
180
    {
181
        $receipt = new Receipt('payping', $referenceId);
182
183
        return $receipt;
184
    }
185
186
    /**
187
     * Trigger an exception
188
     *
189
     * @param $message
190
     *
191
     * @throws InvalidPaymentException
192
     */
193
    private function notVerified($message)
194
    {
195
        throw new InvalidPaymentException($message);
196
    }
197
198
    /**
199
     * Retrieve related message to given status code
200
     *
201
     * @param $statusCode
202
     *
203
     * @return string
204
     */
205
    private function convertStatusCodeToMessage(int $statusCode) : string
206
    {
207
        $messages = [
208
            400 => 'مشکلی در ارسال درخواست وجود دارد',
209
            401 => 'عدم دسترسی',
210
            403 => 'دسترسی غیر مجاز',
211
            404 => 'آیتم درخواستی مورد نظر موجود نمی باشد',
212
            500 => 'مشکلی در سرور درگاه پرداخت رخ داده است',
213
            503 => 'سرور درگاه پرداخت در حال حاضر قادر به پاسخگویی نمی باشد',
214
        ];
215
216
        $unknown = 'خطای ناشناخته ای در درگاه پرداخت رخ داده است';
217
218
        return $messages[$statusCode] ?? $unknown;
219
    }
220
}
221