Completed
Push — master ( ae9e7e...ad16af )
by Kazi Mainuddin
01:37
created

PaymentController   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 4
dl 0
loc 205
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A index() 0 8 1
A payment() 0 17 1
A bootstrap() 0 5 1
A getPaymentFormInformation() 0 11 2
A getHashChecksum() 0 15 3
A validateRequest() 0 16 2
A generatePaymentObject() 0 21 3
A getFormDataArray() 0 12 3
A getStatusUrl() 0 10 2
A getFormFields() 0 19 2
1
<?php
2
namespace Tzsk\Payu\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Session;
7
use Illuminate\Support\Facades\Validator;
8
use Tzsk\Payu\Helpers\Config;
9
use Tzsk\Payu\Helpers\Storage;
10
use Tzsk\Payu\Model\PayuPayment;
11
use Tzsk\Payu\ProcessPayment;
12
13
class PaymentController extends Controller
14
{
15
    /**
16
     * @var Config
17
     */
18
    protected $config;
19
20
    /**
21
     * @var Storage
22
     */
23
    protected $storage;
24
25
    /**
26
     * Got to payment.
27
     *
28
     * @param Request $request
29
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
30
     */
31
    public function index(Request $request)
32
    {
33
        $this->bootstrap();
34
35
        $payment = $this->getPaymentFormInformation($request);
36
37
        return view('tzsk::payment_form', compact('payment'));
38
    }
39
40
    /**
41
     * After payment it will return here.
42
     *
43
     * @param Request $request
44
     * @return \Illuminate\Http\RedirectResponse
45
     */
46
    public function payment(Request $request)
47
    {
48
        $this->bootstrap();
49
50
        $attributes = $request->only([
51
            'txnid', 'mihpayid', 'firstname', 'email', 'phone', 'amount', 'discount',
52
            'net_amount_debit', 'data', 'status', 'unmappedstatus', 'mode', 'bank_ref_num',
53
            'bankcode', 'cardnum', 'name_on_card', 'issuing_bank', 'card_type'
54
        ]);
55
        $attributes['data'] = json_encode($request->all());
56
        $process = new ProcessPayment($request);
57
        $attributes['status'] = $process->getStatus();
58
59
        $this->generatePaymentObject($attributes);
60
61
        return redirect()->to(base64_decode($request->callback));
62
    }
63
64
    /**
65
     * Bootstrap the Payment Controller.
66
     */
67
    protected function bootstrap()
68
    {
69
        $this->config = new Config();
70
        $this->storage = new Storage();
71
    }
72
73
    /**
74
     * @param  Request $request
75
     * @return object
76
     * @throws \Exception
77
     */
78
    protected function getPaymentFormInformation(Request $request)
79
    {
80
        $form_fields = $this->getFormFields($request);
81
82
        $prefix = ($this->config->getEnv() == 'secure') ? 'secure' : 'test';
83
        $url = "https://{$prefix}.".$this->config->getEndpoint();
84
85
        $payment = (object) ['fields' => $form_fields, 'url' => $url];
86
87
        return $payment;
88
    }
89
90
    /**
91
     * @param Request $request
92
     * @return string
93
     */
94
    protected function getHashChecksum(Request $request)
95
    {
96
        $fields = array_merge($this->config->getRequiredFields(), $this->config->getOptionalFields());
97
98
        $hash_array = [];
99
        foreach (collect($fields)->flip()->except(['phone'])->flip() as $field) {
100
            $hash_array[] = $request->has($field) ? $request->get($field) : "";
101
        }
102
103
        $checksum_array = array_merge([$this->config->getKey()], $hash_array, [$this->config->getSalt()]);
104
105
        $hash = hash('sha512', implode('|', $checksum_array));
106
107
        return $hash;
108
    }
109
110
    /**
111
     * @param Request $request
112
     * @return array
113
     */
114
    protected function validateRequest(Request $request)
115
    {
116
        $validation = collect(array_flip($this->config->getRequiredFields()))->map(function () {
117
            return 'required';
118
        })->all();
119
120
        $data = $this->getFormDataArray($request);
121
122
        $validator = Validator::make($request->all(), $validation);
123
124
        if ($validator->fails()) {
125
            throw new \InvalidArgumentException($validator->errors()->first());
126
        }
127
128
        return $data;
129
    }
130
131
    /**
132
     * Generate the payment model Object for use.
133
     *
134
     * @param $attributes
135
     */
136
    protected function generatePaymentObject($attributes)
137
    {
138
        $model = $this->storage->getModel();
139
140
        if ($this->config->getDriver() == 'database') {
141
            $payment_instance = PayuPayment::create($attributes);
142
143
            if (!empty($model)) {
144
                $payment_instance->fill([
145
                    'payable_id' => $model['id'],
146
                    'payable_type' => $model['class']
147
                ])->save();
148
            }
149
150
            $payment = $payment_instance->id;
151
        } else {
152
            $payment = $attributes;
153
        }
154
155
        Session::put('tzsk_payu_data.payment', $payment);
156
    }
157
158
    /**
159
     * Get the form data array.
160
     *
161
     * @param Request $request
162
     * @return array
163
     */
164
    private function getFormDataArray(Request $request)
165
    {
166
        $data = [];
167
        $items = collect($this->config->getRequiredFields())->merge($this->config->getOptionalFields())
168
            ->merge($this->config->getAdditionalFields());
169
170
        foreach ($items as $item) {
171
            $request->has($item) ? $data[$item] = $request->get($item) : null;
172
        }
173
174
        return $data;
175
    }
176
177
    /**
178
     * Get Status url.
179
     *
180
     * @return string
181
     * @throws \Exception
182
     */
183
    private function getStatusUrl()
184
    {
185
        $status_url = $this->storage->getStatusUrl();
186
187
        if (empty($status_url)) {
188
            throw new \Exception("There is no Redirect URL specified.");
189
        }
190
191
        return urlencode(base64_encode($status_url));
192
    }
193
194
    /**
195
     * @param Request $request
196
     * @return array
197
     */
198
    protected function getFormFields(Request $request)
199
    {
200
        $data = $this->storage->getData();
201
        $status_url = $this->getStatusUrl();
202
203
        $request->replace($data);
204
        $validation = $this->validateRequest($request);
205
        $hash = $this->getHashChecksum($request);
206
207
        $redirect = collect($this->config->getRedirect())->map(function ($value) use ($request, $status_url) {
208
            $separator = str_contains($value, '?') ? '&' : '?';
209
            return url($value.$separator.'_token='.csrf_token().'&'.'callback='.$status_url);
210
        })->all();
211
212
        $form_fields = array_merge(['key' => $this->config->getKey(), 'hash' => $hash],
213
            array_merge($redirect, $validation));
214
215
        return $form_fields;
216
    }
217
}
218